diff options
author | nyamatongwe <devnull@localhost> | 2011-08-07 13:41:35 +1000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2011-08-07 13:41:35 +1000 |
commit | b510d1fe619eff95c7e0d0a88421b8e3cad8f729 (patch) | |
tree | 595b5f8217a081087316de368c15d7c0a4f586b4 | |
parent | a320c92efc362ad68b903e73e848b4e8781fa4ec (diff) | |
download | scintilla-mirror-b510d1fe619eff95c7e0d0a88421b8e3cad8f729.tar.gz |
Implement APIs for fractional font sizes and a range of weights.
-rw-r--r-- | include/Platform.h | 2 | ||||
-rw-r--r-- | include/Scintilla.h | 8 | ||||
-rw-r--r-- | include/Scintilla.iface | 19 | ||||
-rw-r--r-- | src/Editor.cxx | 18 | ||||
-rw-r--r-- | src/Style.cxx | 20 | ||||
-rw-r--r-- | src/Style.h | 8 | ||||
-rw-r--r-- | src/ViewStyle.cxx | 12 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 57 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 8 |
9 files changed, 97 insertions, 55 deletions
diff --git a/include/Platform.h b/include/Platform.h index d4c6bbfec..d23a932e4 100644 --- a/include/Platform.h +++ b/include/Platform.h @@ -304,7 +304,7 @@ public: virtual ~Font(); virtual void Create(const char *faceName, int characterSet, float size, - bool bold, bool italic, int extraFontFlag=0); + int weight, bool italic, int extraFontFlag=0); virtual void Release(); FontID GetID() { return fid; } diff --git a/include/Scintilla.h b/include/Scintilla.h index 34e4f793d..c7b9944d8 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -221,6 +221,14 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_STYLEGETCHANGEABLE 2492 #define SCI_STYLEGETHOTSPOT 2493 #define SCI_STYLESETCASE 2060 +#define SC_FONT_SIZE_MULTIPLIER 100 +#define SCI_STYLESETSIZEFRACTIONAL 2061 +#define SCI_STYLEGETSIZEFRACTIONAL 2062 +#define SC_WEIGHT_NORMAL 400 +#define SC_WEIGHT_SEMIBOLD 600 +#define SC_WEIGHT_BOLD 700 +#define SCI_STYLESETWEIGHT 2063 +#define SCI_STYLEGETWEIGHT 2064 #define SCI_STYLESETCHARACTERSET 2066 #define SCI_STYLESETHOTSPOT 2409 #define SCI_SETSELFORE 2067 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 36ead0ece..c604f621a 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -482,6 +482,25 @@ get bool StyleGetHotSpot=2493(int style,) # Set a style to be mixed case, or to force upper or lower case. set void StyleSetCase=2060(int style, int caseForce) +val SC_FONT_SIZE_MULTIPLIER=100 + +# Set the size of characters of a style. Size is in points multiplied by 100. +set void StyleSetSizeFractional=2061(int style, int caseForce) + +# Get the weight of characters of a style in points multiplied by 100 +get int StyleGetSizeFractional=2062(int style,) + +enu FontWeight=SC_WEIGHT_ +val SC_WEIGHT_NORMAL=400 +val SC_WEIGHT_SEMIBOLD=600 +val SC_WEIGHT_BOLD=700 + +# Get the weight of characters of a style. +set void StyleSetWeight=2063(int style, int weight) + +# Get the weight of characters of a style. +get int StyleGetWeight=2064(int style,) + # Set the character set of the font in a style. set void StyleSetCharacterSet=2066(int style, int characterSet) diff --git a/src/Editor.cxx b/src/Editor.cxx index f44279bbd..7261ac7d2 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -6981,7 +6981,10 @@ void Editor::StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam vs.styles[wParam].back.desired = ColourDesired(lParam); break; case SCI_STYLESETBOLD: - vs.styles[wParam].bold = lParam != 0; + vs.styles[wParam].weight = lParam != 0 ? SC_WEIGHT_BOLD : SC_WEIGHT_NORMAL; + break; + case SCI_STYLESETWEIGHT: + vs.styles[wParam].weight = lParam; break; case SCI_STYLESETITALIC: vs.styles[wParam].italic = lParam != 0; @@ -6990,6 +6993,9 @@ void Editor::StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam vs.styles[wParam].eolFilled = lParam != 0; break; case SCI_STYLESETSIZE: + vs.styles[wParam].size = lParam * SC_FONT_SIZE_MULTIPLIER; + break; + case SCI_STYLESETSIZEFRACTIONAL: vs.styles[wParam].size = lParam; break; case SCI_STYLESETFONT: @@ -7027,12 +7033,16 @@ sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lPar case SCI_STYLEGETBACK: return vs.styles[wParam].back.desired.AsLong(); case SCI_STYLEGETBOLD: - return vs.styles[wParam].bold ? 1 : 0; + return vs.styles[wParam].weight > SC_WEIGHT_NORMAL; + case SCI_STYLEGETWEIGHT: + return vs.styles[wParam].weight; case SCI_STYLEGETITALIC: return vs.styles[wParam].italic ? 1 : 0; case SCI_STYLEGETEOLFILLED: return vs.styles[wParam].eolFilled ? 1 : 0; case SCI_STYLEGETSIZE: + return vs.styles[wParam].size / SC_FONT_SIZE_MULTIPLIER; + case SCI_STYLEGETSIZEFRACTIONAL: return vs.styles[wParam].size; case SCI_STYLEGETFONT: if (!vs.styles[wParam].fontName) @@ -8150,9 +8160,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_STYLESETFORE: case SCI_STYLESETBACK: case SCI_STYLESETBOLD: + case SCI_STYLESETWEIGHT: case SCI_STYLESETITALIC: case SCI_STYLESETEOLFILLED: case SCI_STYLESETSIZE: + case SCI_STYLESETSIZEFRACTIONAL: case SCI_STYLESETFONT: case SCI_STYLESETUNDERLINE: case SCI_STYLESETCASE: @@ -8166,9 +8178,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_STYLEGETFORE: case SCI_STYLEGETBACK: case SCI_STYLEGETBOLD: + case SCI_STYLEGETWEIGHT: case SCI_STYLEGETITALIC: case SCI_STYLEGETEOLFILLED: case SCI_STYLEGETSIZE: + case SCI_STYLEGETSIZEFRACTIONAL: case SCI_STYLEGETFONT: case SCI_STYLEGETUNDERLINE: case SCI_STYLEGETCASE: diff --git a/src/Style.cxx b/src/Style.cxx index fc250f0bc..0a38cd6a5 100644 --- a/src/Style.cxx +++ b/src/Style.cxx @@ -33,7 +33,7 @@ void FontAlias::ClearFont() { } bool FontSpecification::EqualTo(const FontSpecification &other) const { - return bold == other.bold && + return weight == other.weight && italic == other.italic && size == other.size && characterSet == other.characterSet && @@ -56,18 +56,18 @@ void FontMeasurements::Clear() { Style::Style() : FontSpecification() { Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), - Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT, - false, false, false, false, caseMixed, true, true, false); + Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, 0, SC_CHARSET_DEFAULT, + SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); } Style::Style(const Style &source) : FontSpecification(), FontMeasurements() { Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), 0, 0, 0, - false, false, false, false, caseMixed, true, true, false); + SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; - bold = source.bold; + weight = source.weight; italic = source.italic; size = source.size; eolFilled = source.eolFilled; @@ -86,11 +86,11 @@ Style &Style::operator=(const Style &source) { return * this; Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), 0, 0, SC_CHARSET_DEFAULT, - false, false, false, false, caseMixed, true, true, false); + SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; - bold = source.bold; + weight = source.weight; italic = source.italic; size = source.size; eolFilled = source.eolFilled; @@ -103,13 +103,13 @@ Style &Style::operator=(const Style &source) { void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_, const char *fontName_, int characterSet_, - bool bold_, bool italic_, bool eolFilled_, + int weight_, bool italic_, bool eolFilled_, bool underline_, ecaseForced caseForce_, bool visible_, bool changeable_, bool hotspot_) { fore.desired = fore_; back.desired = back_; characterSet = characterSet_; - bold = bold_; + weight = weight_; italic = italic_; size = size_; fontName = fontName_; @@ -130,7 +130,7 @@ void Style::ClearTo(const Style &source) { source.size, source.fontName, source.characterSet, - source.bold, + source.weight, source.italic, source.eolFilled, source.underline, diff --git a/src/Style.h b/src/Style.h index 29122b0a4..0e706d322 100644 --- a/src/Style.h +++ b/src/Style.h @@ -14,16 +14,16 @@ namespace Scintilla { struct FontSpecification { const char *fontName; - bool bold; + int weight; bool italic; int size; int characterSet; int extraFontFlag; FontSpecification() : fontName(0), - bold(false), + weight(SC_WEIGHT_NORMAL), italic(false), - size(10), + size(10 * SC_FONT_SIZE_MULTIPLIER), characterSet(0), extraFontFlag(0) { } @@ -77,7 +77,7 @@ public: void Clear(ColourDesired fore_, ColourDesired back_, int size_, const char *fontName_, int characterSet_, - bool bold_, bool italic_, bool eolFilled_, + int weight_, bool italic_, bool eolFilled_, bool underline_, ecaseForced caseForce_, bool visible_, bool changeable_, bool hotspot_); void ClearTo(const Style &source); diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx index 9ba69b1ce..b46cd9eb4 100644 --- a/src/ViewStyle.cxx +++ b/src/ViewStyle.cxx @@ -88,12 +88,12 @@ FontRealised::~FontRealised() { void FontRealised::Realise(Surface &surface, int zoomLevel) { PLATFORM_ASSERT(fontName); - sizeZoomed = size + zoomLevel; - if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1 - sizeZoomed = 2; + sizeZoomed = size + zoomLevel * SC_FONT_SIZE_MULTIPLIER; + if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER) // Hangs if sizeZoomed <= 1 + sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER; int deviceHeight = surface.DeviceHeightFont(sizeZoomed); - font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag); + font.Create(fontName, characterSet, deviceHeight, weight, italic, extraFontFlag); ascent = surface.Ascent(font); descent = surface.Descent(font); @@ -457,9 +457,9 @@ void ViewStyle::EnsureStyle(size_t index) { void ViewStyle::ResetDefaultStyle() { styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), ColourDesired(0xff,0xff,0xff), - Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()), + Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, fontNames.Save(Platform::DefaultFont()), SC_CHARSET_DEFAULT, - false, false, false, false, Style::caseMixed, true, true, false); + SC_WEIGHT_NORMAL, false, false, false, Style::caseMixed, true, true, false); } void ViewStyle::ClearStyles() { diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index acbb5f62d..b22cd10a1 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -242,11 +242,13 @@ static BYTE Win32MapFontQuality(int extraFontFlag) { } } -static void SetLogFont(LOGFONTA &lf, const char *faceName, int characterSet, int size, bool bold, bool italic, int extraFontFlag) { +const int fontSizeMultiplier = 100; + +static void SetLogFont(LOGFONTA &lf, const char *faceName, int characterSet, float size, int weight, bool italic, int extraFontFlag) { memset(&lf, 0, sizeof(lf)); // The negative is to allow for leading - lf.lfHeight = -(abs(size)); - lf.lfWeight = bold ? FW_BOLD : FW_NORMAL; + lf.lfHeight = -(abs(static_cast<int>(size/fontSizeMultiplier))); + lf.lfWeight = weight; lf.lfItalic = static_cast<BYTE>(italic ? 1 : 0); lf.lfCharSet = static_cast<BYTE>(characterSet); lf.lfQuality = Win32MapFontQuality(extraFontFlag); @@ -258,12 +260,12 @@ static void SetLogFont(LOGFONTA &lf, const char *faceName, int characterSet, int * If one font is the same as another, its hash will be the same, but if the hash is the * same then they may still be different. */ -static int HashFont(const char *faceName, int characterSet, int size, bool bold, bool italic, int extraFontFlag) { +static int HashFont(const char *faceName, int characterSet, float size, int weight, bool italic, int extraFontFlag) { return - size ^ + static_cast<int>((size / fontSizeMultiplier)) ^ (characterSet << 10) ^ ((extraFontFlag & SC_EFF_QUALITY_MASK) << 9) ^ - (bold ? 0x10000000 : 0) ^ + ((weight/100) << 12) ^ (italic ? 0x20000000 : 0) ^ faceName[0]; } @@ -271,25 +273,26 @@ static int HashFont(const char *faceName, int characterSet, int size, bool bold, class FontCached : Font { FontCached *next; int usage; + float size; LOGFONTA lf; int hash; - FontCached(const char *faceName_, int characterSet_, float size_, bool bold_, bool italic_, int extraFontFlag_); + FontCached(const char *faceName_, int characterSet_, float size_, int weight_, bool italic_, int extraFontFlag_); ~FontCached() {} - bool SameAs(const char *faceName_, int characterSet_, float size_, bool bold_, bool italic_, int extraFontFlag_); + bool SameAs(const char *faceName_, int characterSet_, float size_, int weight_, bool italic_, int extraFontFlag_); virtual void Release(); static FontCached *first; public: - static FontID FindOrCreate(const char *faceName_, int characterSet_, float size_, bool bold_, bool italic_, int extraFontFlag_); + static FontID FindOrCreate(const char *faceName_, int characterSet_, float size_, int weight_, bool italic_, int extraFontFlag_); static void ReleaseId(FontID fid_); }; FontCached *FontCached::first = 0; -FontCached::FontCached(const char *faceName_, int characterSet_, float size_, bool bold_, bool italic_, int extraFontFlag_) : - next(0), usage(0), hash(0) { - SetLogFont(lf, faceName_, characterSet_, size_, bold_, italic_, extraFontFlag_); - hash = HashFont(faceName_, characterSet_, size_, bold_, italic_, extraFontFlag_); +FontCached::FontCached(const char *faceName_, int characterSet_, float size_, int weight_, bool italic_, int extraFontFlag_) : + next(0), usage(0), size(1.0), hash(0) { + SetLogFont(lf, faceName_, characterSet_, size_, weight_, italic_, extraFontFlag_); + hash = HashFont(faceName_, characterSet_, size_, weight_, italic_, extraFontFlag_); fid = 0; EnsureDWriteFactory(); if (pIDWriteFactory) { @@ -312,11 +315,9 @@ FontCached::FontCached(const char *faceName_, int characterSet_, float size_, bo const int faceSize = 200; WCHAR wszFace[faceSize]; UTF16FromUTF8(faceName_, strlen(faceName_)+1, wszFace, faceSize); - FLOAT fHeight = size_; - if (fHeight > 2000) - fHeight = fHeight / 1000.0f; + FLOAT fHeight = size_ / fontSizeMultiplier; HRESULT hr = pIDWriteFactory->CreateTextFormat(wszFace, NULL, - bold_ ? DWRITE_FONT_WEIGHT_SEMI_BOLD : DWRITE_FONT_WEIGHT_REGULAR, + static_cast<DWRITE_FONT_WEIGHT>(weight_), italic_ ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, fHeight, L"en-us", &pTextFormat); if (SUCCEEDED(hr)) { @@ -325,7 +326,7 @@ FontCached::FontCached(const char *faceName_, int characterSet_, float size_, bo UINT32 lineCount = 0; FLOAT baseline = 1.0f; IDWriteTextLayout *pTextLayout = 0; - HRESULT hr = pIDWriteFactory->CreateTextLayout(L"X", 1, pTextFormat, + hr = pIDWriteFactory->CreateTextLayout(L"X", 1, pTextFormat, 100.0f, 100.0f, &pTextLayout); if (SUCCEEDED(hr)) { hr = pTextLayout->GetLineMetrics(lineMetrics, maxLines, &lineCount); @@ -340,10 +341,10 @@ FontCached::FontCached(const char *faceName_, int characterSet_, float size_, bo usage = 1; } -bool FontCached::SameAs(const char *faceName_, int characterSet_, float size_, bool bold_, bool italic_, int extraFontFlag_) { +bool FontCached::SameAs(const char *faceName_, int characterSet_, float size_, int weight_, bool italic_, int extraFontFlag_) { return - (lf.lfHeight == -(abs(size_))) && - (lf.lfWeight == (bold_ ? FW_BOLD : FW_NORMAL)) && + (size == size_) && + (lf.lfWeight == weight_) && (lf.lfItalic == static_cast<BYTE>(italic_ ? 1 : 0)) && (lf.lfCharSet == characterSet_) && (lf.lfQuality == Win32MapFontQuality(extraFontFlag_)) && @@ -355,19 +356,19 @@ void FontCached::Release() { fid = 0; } -FontID FontCached::FindOrCreate(const char *faceName_, int characterSet_, float size_, bool bold_, bool italic_, int extraFontFlag_) { +FontID FontCached::FindOrCreate(const char *faceName_, int characterSet_, float size_, int weight_, bool italic_, int extraFontFlag_) { FontID ret = 0; ::EnterCriticalSection(&crPlatformLock); - int hashFind = HashFont(faceName_, characterSet_, size_, bold_, italic_, extraFontFlag_); + int hashFind = HashFont(faceName_, characterSet_, size_, weight_, italic_, extraFontFlag_); for (FontCached *cur=first; cur; cur=cur->next) { if ((cur->hash == hashFind) && - cur->SameAs(faceName_, characterSet_, size_, bold_, italic_, extraFontFlag_)) { + cur->SameAs(faceName_, characterSet_, size_, weight_, italic_, extraFontFlag_)) { cur->usage++; ret = cur->fid; } } if (ret == 0) { - FontCached *fc = new FontCached(faceName_, characterSet_, size_, bold_, italic_, extraFontFlag_); + FontCached *fc = new FontCached(faceName_, characterSet_, size_, weight_, italic_, extraFontFlag_); if (fc) { fc->next = first; first = fc; @@ -407,10 +408,10 @@ Font::~Font() { #define FONTS_CACHED void Font::Create(const char *faceName, int characterSet, float size, - bool bold, bool italic, int extraFontFlag) { + int weight, bool italic, int extraFontFlag) { Release(); if (faceName) - fid = FontCached::FindOrCreate(faceName, characterSet, size, bold, italic, extraFontFlag); + fid = FontCached::FindOrCreate(faceName, characterSet, size, weight, italic, extraFontFlag); } void Font::Release() { @@ -515,7 +516,7 @@ public: SurfaceImpl::SurfaceImpl() : unicodeMode(false), hdc(0), hdcOwned(false), - x(0), y(0), { + x(0), y(0) { // Windows 9x has only a 16 bit coordinate system so break after 30000 pixels maxWidthMeasure = IsNT() ? INT_MAX : 30000; // There appears to be a 16 bit string length limit in GDI on NT and a limit of diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 28e48596b..6bc770eed 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -2151,9 +2151,9 @@ void ScintillaWin::ImeStartComposition() { // The logfont for the IME is recreated here. int styleHere = (pdoc->StyleAt(sel.MainCaret())) & 31; LOGFONTA lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ""}; - int sizeZoomed = vs.styles[styleHere].size + vs.zoomLevel; - if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1 - sizeZoomed = 2; + int sizeZoomed = vs.styles[styleHere].size + vs.zoomLevel * SC_FONT_SIZE_MULTIPLIER; + if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER) // Hangs if sizeZoomed <= 1 + sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER; AutoSurface surface(this); int deviceHeight = sizeZoomed; if (surface) { @@ -2161,7 +2161,7 @@ void ScintillaWin::ImeStartComposition() { } // The negative is to allow for leading lf.lfHeight = -(abs(deviceHeight)); - lf.lfWeight = vs.styles[styleHere].bold ? FW_BOLD : FW_NORMAL; + lf.lfWeight = vs.styles[styleHere].weight; lf.lfItalic = static_cast<BYTE>(vs.styles[styleHere].italic ? 1 : 0); lf.lfCharSet = DEFAULT_CHARSET; lf.lfFaceName[0] = '\0'; |