Skip to content

Commit dcbc339

Browse files
committed
Add SCI_STYLESETSTRETCH to support condensed and expanded text styles.
1 parent 6f51f59 commit dcbc339

18 files changed

+181
-8
lines changed

call/ScintillaCall.cxx

+8
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,14 @@ bool ScintillaCall::StyleGetCheckMonospaced(int style) {
655655
return Call(Message::StyleGetCheckMonospaced, style);
656656
}
657657

658+
void ScintillaCall::StyleSetStretch(int style, Scintilla::FontStretch stretch) {
659+
Call(Message::StyleSetStretch, style, static_cast<intptr_t>(stretch));
660+
}
661+
662+
FontStretch ScintillaCall::StyleGetStretch(int style) {
663+
return static_cast<Scintilla::FontStretch>(Call(Message::StyleGetStretch, style));
664+
}
665+
658666
void ScintillaCall::StyleSetInvisibleRepresentation(int style, const char *representation) {
659667
CallString(Message::StyleSetInvisibleRepresentation, style, representation);
660668
}

cocoa/PlatCocoa.mm

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ inline CGRect CGRectFromPRectangleInset(PRectangle rc, XYPOSITION strokeWidth) {
106106
FontQuartz(const FontParameters &fp) {
107107
style = std::make_unique<QuartzTextStyle>();
108108
// Create the font with attributes
109-
QuartzFont font(fp.faceName, strlen(fp.faceName), fp.size, fp.weight, fp.italic);
109+
QuartzFont font(fp.faceName, strlen(fp.faceName), fp.size, fp.weight, fp.stretch, fp.italic);
110110
CTFontRef fontRef = font.getFontID();
111111
style->setFontRef(fontRef, fp.characterSet);
112112
}

cocoa/QuartzTextStyleAttribute.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515
class QuartzFont {
1616
public:
1717
/** Create a font style from a name. */
18-
QuartzFont(const char *name, size_t length, float size, Scintilla::FontWeight weight, bool italic) {
18+
QuartzFont(const char *name, size_t length, float size, Scintilla::FontWeight weight, Scintilla::FontStretch stretch, bool italic) {
1919
assert(name != NULL && length > 0 && name[length] == '\0');
2020

2121
CFStringRef fontName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman);
2222
assert(fontName != NULL);
2323
bool bold = weight > Scintilla::FontWeight::Normal;
2424

25-
if (bold || italic) {
25+
if (bold || italic || stretch != Scintilla::FontStretch::Normal) {
2626
CTFontSymbolicTraits desiredTrait = 0;
2727
CTFontSymbolicTraits traitMask = 0;
2828

@@ -37,6 +37,13 @@ class QuartzFont {
3737
desiredTrait |= kCTFontItalicTrait;
3838
traitMask |= kCTFontItalicTrait;
3939
}
40+
if (stretch < Scintilla::FontStretch::Normal) {
41+
desiredTrait |= kCTFontCondensedTrait;
42+
traitMask |= kCTFontCondensedTrait;
43+
} else if (stretch > Scintilla::FontStretch::Normal) {
44+
desiredTrait |= kCTFontExpandedTrait;
45+
traitMask |= kCTFontExpandedTrait;
46+
}
4047

4148
// create a font and then a copy of it with the sym traits
4249
CTFontRef iFont = ::CTFontCreateWithName(fontName, size, NULL);

doc/ScintillaDoc.html

+66
Original file line numberDiff line numberDiff line change
@@ -3348,6 +3348,8 @@ <h2 id="StyleDefinition">Style definition</h2>
33483348
<a class="message" href="#SCI_STYLESETWEIGHT">SCI_STYLESETWEIGHT(int style, int
33493349
weight)</a><br />
33503350
<a class="message" href="#SCI_STYLEGETWEIGHT">SCI_STYLEGETWEIGHT(int style) &rarr; int</a><br />
3351+
<a class="message" href="#SCI_STYLESETSTRETCH">SCI_STYLESETSTRETCH(int style, int stretch)</a><br />
3352+
<a class="message" href="#SCI_STYLEGETSTRETCH">SCI_STYLEGETSTRETCH(int style) &rarr; int</a><br />
33513353
<a class="message" href="#SCI_STYLESETITALIC">SCI_STYLESETITALIC(int style, bool
33523354
italic)</a><br />
33533355
<a class="message" href="#SCI_STYLEGETITALIC">SCI_STYLEGETITALIC(int style) &rarr; bool</a><br />
@@ -3407,6 +3409,8 @@ <h2 id="StyleDefinition">Style definition</h2>
34073409
<b id="SCI_STYLEGETBOLD">SCI_STYLEGETBOLD(int style) &rarr; bool</b><br />
34083410
<b id="SCI_STYLESETWEIGHT">SCI_STYLESETWEIGHT(int style, int weight)</b><br />
34093411
<b id="SCI_STYLEGETWEIGHT">SCI_STYLEGETWEIGHT(int style) &rarr; int</b><br />
3412+
<b id="SCI_STYLESETSTRETCH">SCI_STYLESETSTRETCH(int style, int stretch)</b><br />
3413+
<b id="SCI_STYLEGETSTRETCH">SCI_STYLEGETSTRETCH(int style) &rarr; int</b><br />
34103414
<b id="SCI_STYLESETITALIC">SCI_STYLESETITALIC(int style, bool italic)</b><br />
34113415
<b id="SCI_STYLEGETITALIC">SCI_STYLEGETITALIC(int style) &rarr; bool</b><br />
34123416
These messages (plus <a class="message"
@@ -3435,6 +3439,68 @@ <h2 id="StyleDefinition">Style definition</h2>
34353439
The <code>SCI_STYLESETBOLD</code> message takes a boolean argument with 0 choosing <code>SC_WEIGHT_NORMAL</code>
34363440
and 1 <code>SC_WEIGHT_BOLD</code>.
34373441
</p>
3442+
<p>The stretch of a font can be set with <code>SCI_STYLESETSTRETCH</code> which can produce condensed or expanded text.
3443+
The weight is a number between 1 and 9 which corresponds to a horizontal magnification between 50% and 200%
3444+
with 1 being very condensed, 5 normal, and 9 very expanded.
3445+
While any value can be used, fonts and platforms often only support between 2 and 3 stretches.
3446+
The best supported and useful values are
3447+
<code>SC_STRETCH_CONDENSED</code>,
3448+
<code>SC_STRETCH_NORMAL</code>, and
3449+
<code>SC_STRETCH_EXPANDED</code>.
3450+
The Inconsolata variable font supports many stretch values and can be useful for experimenting.
3451+
Condensed text can be used to display more text in a narrower window and expanded text may be used
3452+
for clearer text that is easier to read.
3453+
The API is based on the Cascading Style Sheets font-stretch property.
3454+
</p>
3455+
<table class="standard" summary="Stretch">
3456+
<tbody valign="top">
3457+
<tr>
3458+
<th align="left"><code>SC_STRETCH_ULTRA_CONDENSED</code></th>
3459+
<td>1</td>
3460+
<td>50%</td>
3461+
</tr>
3462+
<tr>
3463+
<th align="left"><code>SC_STRETCH_EXTRA_CONDENSED</code></th>
3464+
<td>2</td>
3465+
<td>62.5%</td>
3466+
</tr>
3467+
<tr>
3468+
<th align="left"><code>SC_STRETCH_CONDENSED</code></th>
3469+
<td>3</td>
3470+
<td>75%</td>
3471+
</tr>
3472+
<tr>
3473+
<th align="left"><code>SC_STRETCH_SEMI_CONDENSED</code></th>
3474+
<td>4</td>
3475+
<td>87.5%</td>
3476+
</tr>
3477+
<tr>
3478+
<th align="left"><code>SC_STRETCH_NORMAL</code></th>
3479+
<td>5</td>
3480+
<td>100%</td>
3481+
</tr>
3482+
<tr>
3483+
<th align="left"><code>SC_STRETCH_SEMI_EXPANDED</code></th>
3484+
<td>6</td>
3485+
<td>112.5%</td>
3486+
</tr>
3487+
<tr>
3488+
<th align="left"><code>SC_STRETCH_EXPANDED</code></th>
3489+
<td>7</td>
3490+
<td>125%</td>
3491+
</tr>
3492+
<tr>
3493+
<th align="left"><code>SC_STRETCH_EXTRA_EXPANDED</code></th>
3494+
<td>8</td>
3495+
<td>150%</td>
3496+
</tr>
3497+
<tr>
3498+
<th align="left"><code>SC_STRETCH_ULTRA_EXPANDED</code></th>
3499+
<td>9</td>
3500+
<td>200%</td>
3501+
</tr>
3502+
</tbody>
3503+
</table>
34383504

34393505
<p><b id="SCI_STYLESETUNDERLINE">SCI_STYLESETUNDERLINE(int style, bool
34403506
underline)</b><br />

doc/ScintillaHistory.html

+3
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,9 @@ <h3>
600600
Add SCI_GETUNDOSEQUENCE to determine whether an undo sequence is active and its nesting depth.
601601
</li>
602602
<li>
603+
Add SCI_STYLESETSTRETCH to support condensed and expanded text styles.
604+
</li>
605+
<li>
603606
Add SCI_LINEINDENT and SCI_LINEDEDENT.
604607
<a href="https://sourceforge.net/p/scintilla/feature-requests/1524/">Feature #1524</a>.
605608
</li>

gtk/PlatGTK.cxx

+2
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ class FontHandle : public Font {
100100
pango_font_description_set_size(fd.get(), pango_units_from_double(fp.size));
101101
pango_font_description_set_weight(fd.get(), static_cast<PangoWeight>(fp.weight));
102102
pango_font_description_set_style(fd.get(), fp.italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
103+
pango_font_description_set_stretch(fd.get(),
104+
static_cast<PangoStretch>(static_cast<int>(fp.stretch)-1));
103105
}
104106
}
105107
~FontHandle() override = default;

include/Scintilla.h

+11
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,17 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
282282
#define SCI_STYLESETHOTSPOT 2409
283283
#define SCI_STYLESETCHECKMONOSPACED 2254
284284
#define SCI_STYLEGETCHECKMONOSPACED 2255
285+
#define SC_STRETCH_ULTRA_CONDENSED 1
286+
#define SC_STRETCH_EXTRA_CONDENSED 2
287+
#define SC_STRETCH_CONDENSED 3
288+
#define SC_STRETCH_SEMI_CONDENSED 4
289+
#define SC_STRETCH_NORMAL 5
290+
#define SC_STRETCH_SEMI_EXPANDED 6
291+
#define SC_STRETCH_EXPANDED 7
292+
#define SC_STRETCH_EXTRA_EXPANDED 8
293+
#define SC_STRETCH_ULTRA_EXPANDED 9
294+
#define SCI_STYLESETSTRETCH 2258
295+
#define SCI_STYLEGETSTRETCH 2259
285296
#define SCI_STYLESETINVISIBLEREPRESENTATION 2256
286297
#define SCI_STYLEGETINVISIBLEREPRESENTATION 2257
287298
#define SC_ELEMENT_LIST 0

include/Scintilla.iface

+17
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,23 @@ set void StyleSetCheckMonospaced=2254(int style, bool checkMonospaced)
700700
# Get whether a style may be monospaced.
701701
get bool StyleGetCheckMonospaced=2255(int style,)
702702

703+
enu FontStretch=SC_STRETCH_
704+
val SC_STRETCH_ULTRA_CONDENSED=1
705+
val SC_STRETCH_EXTRA_CONDENSED=2
706+
val SC_STRETCH_CONDENSED=3
707+
val SC_STRETCH_SEMI_CONDENSED=4
708+
val SC_STRETCH_NORMAL=5
709+
val SC_STRETCH_SEMI_EXPANDED=6
710+
val SC_STRETCH_EXPANDED=7
711+
val SC_STRETCH_EXTRA_EXPANDED=8
712+
val SC_STRETCH_ULTRA_EXPANDED=9
713+
714+
# Set the stretch of characters of a style.
715+
set void StyleSetStretch=2258(int style, FontStretch stretch)
716+
717+
# Get the stretch of characters of a style.
718+
get FontStretch StyleGetStretch=2259(int style,)
719+
703720
# Set the invisible representation for a style.
704721
set void StyleSetInvisibleRepresentation=2256(int style, string representation)
705722

include/ScintillaCall.h

+2
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ class ScintillaCall {
209209
void StyleSetHotSpot(int style, bool hotspot);
210210
void StyleSetCheckMonospaced(int style, bool checkMonospaced);
211211
bool StyleGetCheckMonospaced(int style);
212+
void StyleSetStretch(int style, Scintilla::FontStretch stretch);
213+
Scintilla::FontStretch StyleGetStretch(int style);
212214
void StyleSetInvisibleRepresentation(int style, const char *representation);
213215
int StyleGetInvisibleRepresentation(int style, char *representation);
214216
std::string StyleGetInvisibleRepresentation(int style);

include/ScintillaMessages.h

+2
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ enum class Message {
137137
StyleSetHotSpot = 2409,
138138
StyleSetCheckMonospaced = 2254,
139139
StyleGetCheckMonospaced = 2255,
140+
StyleSetStretch = 2258,
141+
StyleGetStretch = 2259,
140142
StyleSetInvisibleRepresentation = 2256,
141143
StyleGetInvisibleRepresentation = 2257,
142144
SetElementColour = 2753,

include/ScintillaTypes.h

+12
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,18 @@ enum class FontWeight {
165165
Bold = 700,
166166
};
167167

168+
enum class FontStretch {
169+
UltraCondensed = 1,
170+
ExtraCondensed = 2,
171+
Condensed = 3,
172+
SemiCondensed = 4,
173+
Normal = 5,
174+
SemiExpanded = 6,
175+
Expanded = 7,
176+
ExtraExpanded = 8,
177+
UltraExpanded = 9,
178+
};
179+
168180
enum class Element {
169181
List = 0,
170182
ListBack = 1,

qt/ScintillaEditBase/PlatQt.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,32 @@ static QFont::StyleStrategy ChooseStrategy(FontQuality eff)
113113
}
114114
}
115115

116+
static QFont::Stretch QStretchFromFontStretch(Scintilla::FontStretch stretch)
117+
{
118+
switch (stretch) {
119+
case FontStretch::UltraCondensed:
120+
return QFont::Stretch::UltraCondensed;
121+
case FontStretch::ExtraCondensed:
122+
return QFont::Stretch::ExtraCondensed;
123+
case FontStretch::Condensed:
124+
return QFont::Stretch::Condensed;
125+
case FontStretch::SemiCondensed:
126+
return QFont::Stretch::SemiCondensed;
127+
case FontStretch::Normal:
128+
return QFont::Stretch::Unstretched;
129+
case FontStretch::SemiExpanded:
130+
return QFont::Stretch::SemiExpanded;
131+
case FontStretch::Expanded:
132+
return QFont::Stretch::Expanded;
133+
case FontStretch::ExtraExpanded:
134+
return QFont::Stretch::ExtraExpanded;
135+
case FontStretch::UltraExpanded:
136+
return QFont::Stretch::UltraExpanded;
137+
default:
138+
return QFont::Stretch::Unstretched;
139+
}
140+
}
141+
116142
class FontAndCharacterSet : public Font {
117143
public:
118144
CharacterSet characterSet = CharacterSet::Ansi;
@@ -123,6 +149,7 @@ class FontAndCharacterSet : public Font {
123149
pfont->setFamily(QString::fromUtf8(fp.faceName));
124150
pfont->setPointSizeF(fp.size);
125151
pfont->setBold(static_cast<int>(fp.weight) > 500);
152+
pfont->setStretch(QStretchFromFontStretch(fp.stretch));
126153
pfont->setItalic(fp.italic);
127154
}
128155
};

src/Editor.cxx

+7
Original file line numberDiff line numberDiff line change
@@ -5953,6 +5953,9 @@ void Editor::StyleSetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {
59535953
case Message::StyleSetWeight:
59545954
vs.styles[wParam].weight = static_cast<FontWeight>(lParam);
59555955
break;
5956+
case Message::StyleSetStretch:
5957+
vs.styles[wParam].stretch = static_cast<FontStretch>(lParam);
5958+
break;
59565959
case Message::StyleSetItalic:
59575960
vs.styles[wParam].italic = lParam != 0;
59585961
break;
@@ -6022,6 +6025,8 @@ sptr_t Editor::StyleGetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {
60226025
return vs.styles[wParam].weight > FontWeight::Normal;
60236026
case Message::StyleGetWeight:
60246027
return static_cast<sptr_t>(vs.styles[wParam].weight);
6028+
case Message::StyleGetStretch:
6029+
return static_cast<sptr_t>(vs.styles[wParam].stretch);
60256030
case Message::StyleGetItalic:
60266031
return vs.styles[wParam].italic ? 1 : 0;
60276032
case Message::StyleGetEOLFilled:
@@ -7580,6 +7585,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
75807585
case Message::StyleSetBack:
75817586
case Message::StyleSetBold:
75827587
case Message::StyleSetWeight:
7588+
case Message::StyleSetStretch:
75837589
case Message::StyleSetItalic:
75847590
case Message::StyleSetEOLFilled:
75857591
case Message::StyleSetSize:
@@ -7600,6 +7606,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
76007606
case Message::StyleGetBack:
76017607
case Message::StyleGetBold:
76027608
case Message::StyleGetWeight:
7609+
case Message::StyleGetStretch:
76037610
case Message::StyleGetItalic:
76047611
case Message::StyleGetEOLFilled:
76057612
case Message::StyleGetSize:

src/Platform.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ struct FontParameters {
108108
Scintilla::Technology technology;
109109
Scintilla::CharacterSet characterSet;
110110
const char *localeName;
111+
Scintilla::FontStretch stretch;
111112

112113
constexpr FontParameters(
113114
const char *faceName_,
@@ -117,7 +118,8 @@ struct FontParameters {
117118
Scintilla::FontQuality extraFontFlag_= Scintilla::FontQuality::QualityDefault,
118119
Scintilla::Technology technology_= Scintilla::Technology::Default,
119120
Scintilla::CharacterSet characterSet_= Scintilla::CharacterSet::Ansi,
120-
const char *localeName_=localeNameDefault) noexcept :
121+
const char *localeName_=localeNameDefault,
122+
Scintilla::FontStretch stretch_=Scintilla::FontStretch::Normal) noexcept :
121123

122124
faceName(faceName_),
123125
size(size_),
@@ -126,7 +128,8 @@ struct FontParameters {
126128
extraFontFlag(extraFontFlag_),
127129
technology(technology_),
128130
characterSet(characterSet_),
129-
localeName(localeName_)
131+
localeName(localeName_),
132+
stretch(stretch_)
130133
{
131134
}
132135

src/Style.cxx

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ bool FontSpecification::operator==(const FontSpecification &other) const noexcep
2727
weight == other.weight &&
2828
italic == other.italic &&
2929
size == other.size &&
30+
stretch == other.stretch &&
3031
characterSet == other.characterSet &&
3132
extraFontFlag == other.extraFontFlag &&
3233
checkMonospaced == other.checkMonospaced;
@@ -41,6 +42,8 @@ bool FontSpecification::operator<(const FontSpecification &other) const noexcept
4142
return !italic;
4243
if (size != other.size)
4344
return size < other.size;
45+
if (stretch != other.stretch)
46+
return stretch < other.stretch;
4447
if (characterSet != other.characterSet)
4548
return characterSet < other.characterSet;
4649
if (extraFontFlag != other.extraFontFlag)

src/Style.h

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct FontSpecification {
1515
const char *fontName;
1616
int size;
1717
Scintilla::FontWeight weight = Scintilla::FontWeight::Normal;
18+
Scintilla::FontStretch stretch = Scintilla::FontStretch::Normal;
1819
bool italic = false;
1920
Scintilla::CharacterSet characterSet = Scintilla::CharacterSet::Default;
2021
Scintilla::FontQuality extraFontFlag = Scintilla::FontQuality::QualityDefault;

src/ViewStyle.cxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ void FontRealised::Realise(Surface &surface, int zoomLevel, Technology technolog
6666

6767
const float deviceHeight = static_cast<float>(surface.DeviceHeightFont(measurements.sizeZoomed));
6868
const FontParameters fp(fs.fontName, deviceHeight / FontSizeMultiplier, fs.weight,
69-
fs.italic, fs.extraFontFlag, technology, fs.characterSet, localeName);
69+
fs.italic, fs.extraFontFlag, technology, fs.characterSet, localeName, fs.stretch);
7070
font = Font::Allocate(fp);
7171

7272
// floor here is historical as platform layers have tweaked their values to match.

win32/PlatWin.cxx

+4-2
Original file line numberDiff line numberDiff line change
@@ -347,13 +347,15 @@ struct FontDirectWrite : public FontWin {
347347
HRESULT hr = pIDWriteFactory->CreateTextFormat(wsFace.c_str(), nullptr,
348348
static_cast<DWRITE_FONT_WEIGHT>(fp.weight),
349349
style,
350-
DWRITE_FONT_STRETCH_NORMAL, fHeight, wsLocale.c_str(), &pTextFormat);
350+
static_cast<DWRITE_FONT_STRETCH>(fp.stretch),
351+
fHeight, wsLocale.c_str(), &pTextFormat);
351352
if (hr == E_INVALIDARG) {
352353
// Possibly a bad locale name like "/" so try "en-us".
353354
hr = pIDWriteFactory->CreateTextFormat(wsFace.c_str(), nullptr,
354355
static_cast<DWRITE_FONT_WEIGHT>(fp.weight),
355356
style,
356-
DWRITE_FONT_STRETCH_NORMAL, fHeight, L"en-us", &pTextFormat);
357+
static_cast<DWRITE_FONT_STRETCH>(fp.stretch),
358+
fHeight, L"en-us", &pTextFormat);
357359
}
358360
if (SUCCEEDED(hr)) {
359361
pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);

0 commit comments

Comments
 (0)