aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cocoa/DictionaryForCF.h36
-rw-r--r--cocoa/PlatCocoa.h1
-rw-r--r--cocoa/QuartzTextStyleAttribute.h88
-rw-r--r--cocoa/Scintilla/Scintilla.xcodeproj/project.pbxproj4
-rw-r--r--doc/ScintillaHistory.html3
5 files changed, 99 insertions, 33 deletions
diff --git a/cocoa/DictionaryForCF.h b/cocoa/DictionaryForCF.h
new file mode 100644
index 000000000..09233bab5
--- /dev/null
+++ b/cocoa/DictionaryForCF.h
@@ -0,0 +1,36 @@
+/**
+ * Scintilla source code edit control
+ * @file DictionaryForCF.h - Wrapper for CFMutableDictionary
+ *
+ * Copyright 2024 Neil Hodgson.
+ * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt).
+ */
+
+#ifndef DICTIONARYFORCF_H
+#define DICTIONARYFORCF_H
+
+class DictionaryForCF {
+ CFMutableDictionaryRef dict;
+public:
+ DictionaryForCF() noexcept :
+ dict(::CFDictionaryCreateMutable(kCFAllocatorDefault, 2,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks)) {
+ }
+ ~DictionaryForCF() {
+ ::CFRelease(dict);
+ }
+ CFMutableDictionaryRef get() const noexcept {
+ return dict;
+ }
+ void SetValue(const void *key, const void *value) noexcept {
+ ::CFDictionarySetValue(dict, key, value);
+ }
+ void SetItem(const void *key, CFNumberType theType, const void *valuePtr) noexcept {
+ CFNumberRef number = ::CFNumberCreate(kCFAllocatorDefault, theType, valuePtr);
+ ::CFDictionarySetValue(dict, key, number);
+ ::CFRelease(number);
+ }
+};
+
+#endif
diff --git a/cocoa/PlatCocoa.h b/cocoa/PlatCocoa.h
index 536d3bcf9..0150287f1 100644
--- a/cocoa/PlatCocoa.h
+++ b/cocoa/PlatCocoa.h
@@ -22,6 +22,7 @@
#include "Geometry.h"
#include "Platform.h"
+#include "DictionaryForCF.h"
#include "QuartzTextLayout.h"
NSRect PRectangleToNSRect(const Scintilla::Internal::PRectangle &rc);
diff --git a/cocoa/QuartzTextStyleAttribute.h b/cocoa/QuartzTextStyleAttribute.h
index 22af29b4a..558daa58c 100644
--- a/cocoa/QuartzTextStyleAttribute.h
+++ b/cocoa/QuartzTextStyleAttribute.h
@@ -12,6 +12,42 @@
#ifndef QUARTZTEXTSTYLEATTRIBUTE_H
#define QUARTZTEXTSTYLEATTRIBUTE_H
+// Convert from a FontWeight value to a floating point value to pass to CoreText.
+// This was defined based on Cocoa's NSFontWeight* values, discussion by other open
+// source projects then tweaked until most values produced visibly different results.
+inline double WeightFromEnumeration(Scintilla::FontWeight weight) {
+ switch (static_cast<int>(weight)/100) {
+ case 0: return -1.0;
+ case 1: return -0.7;
+ case 2: return -0.5;
+ case 3: return -0.23;
+ case 4: return 0.0;
+ case 5: return 0.2;
+ case 6: return 0.3;
+ case 7: return 0.4;
+ case 8: return 0.6;
+ case 9: return 0.8;
+ }
+ return 0.0;
+}
+
+// Convert from a FontStretch value to a floating point value to pass to CoreText.
+// This was defined based on values used by other open source projects then tweaked
+// until most values produced reasonable results.
+inline double StretchFromEnumeration(Scintilla::FontStretch stretch) {
+ switch (stretch) {
+ case Scintilla::FontStretch::UltraCondensed: return -0.8;
+ case Scintilla::FontStretch::ExtraCondensed: return -0.3;
+ case Scintilla::FontStretch::Condensed: return -0.23;
+ case Scintilla::FontStretch::SemiCondensed: return -0.1;
+ case Scintilla::FontStretch::Normal: return 0.0;
+ case Scintilla::FontStretch::SemiExpanded: return 0.1;
+ case Scintilla::FontStretch::Expanded: return 0.2;
+ case Scintilla::FontStretch::ExtraExpanded: return 0.3;
+ case Scintilla::FontStretch::UltraExpanded: return 0.7;
+ }
+}
+
class QuartzFont {
public:
/** Create a font style from a name. */
@@ -20,42 +56,28 @@ public:
CFStringRef fontName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman);
assert(fontName != NULL);
- bool bold = weight > Scintilla::FontWeight::Normal;
- if (bold || italic || stretch != Scintilla::FontStretch::Normal) {
- CTFontSymbolicTraits desiredTrait = 0;
- CTFontSymbolicTraits traitMask = 0;
-
- // if bold was specified, add the trait
- if (bold) {
- desiredTrait |= kCTFontBoldTrait;
- traitMask |= kCTFontBoldTrait;
- }
+ // Specify the weight, stretch, and italics
+ DictionaryForCF traits;
+ const double weightValue = WeightFromEnumeration(weight);
+ traits.SetItem(kCTFontWeightTrait, kCFNumberCGFloatType, &weightValue);
+ const double stretchValue = StretchFromEnumeration(stretch);
+ traits.SetItem(kCTFontWidthTrait, kCFNumberCGFloatType, &stretchValue);
+ if (italic) {
+ const int italicValue = kCTFontTraitItalic;
+ traits.SetItem(kCTFontSymbolicTrait, kCFNumberIntType, &italicValue);
+ }
- // if italic was specified, add the trait
- if (italic) {
- desiredTrait |= kCTFontItalicTrait;
- traitMask |= kCTFontItalicTrait;
- }
- if (stretch < Scintilla::FontStretch::Normal) {
- desiredTrait |= kCTFontCondensedTrait;
- traitMask |= kCTFontCondensedTrait;
- } else if (stretch > Scintilla::FontStretch::Normal) {
- desiredTrait |= kCTFontExpandedTrait;
- traitMask |= kCTFontExpandedTrait;
- }
+ // create a font decriptor and then a font with that descriptor
+ DictionaryForCF attributes;
+ attributes.SetValue(kCTFontTraitsAttribute, traits.get());
+ attributes.SetValue(kCTFontNameAttribute, fontName);
- // create a font and then a copy of it with the sym traits
- CTFontRef iFont = ::CTFontCreateWithName(fontName, size, NULL);
- fontid = ::CTFontCreateCopyWithSymbolicTraits(iFont, size, NULL, desiredTrait, traitMask);
- if (fontid) {
- CFRelease(iFont);
- } else {
- // Traits failed so use base font
- fontid = iFont;
- }
- } else {
- // create the font, no traits
+ CTFontDescriptorRef desc = ::CTFontDescriptorCreateWithAttributes(attributes.get());
+ fontid = ::CTFontCreateWithFontDescriptor(desc, size, NULL);
+ CFRelease(desc);
+ if (!fontid) {
+ // Traits failed so use base font
fontid = ::CTFontCreateWithName(fontName, size, NULL);
}
diff --git a/cocoa/Scintilla/Scintilla.xcodeproj/project.pbxproj b/cocoa/Scintilla/Scintilla.xcodeproj/project.pbxproj
index 165ceaf9c..e8f729267 100644
--- a/cocoa/Scintilla/Scintilla.xcodeproj/project.pbxproj
+++ b/cocoa/Scintilla/Scintilla.xcodeproj/project.pbxproj
@@ -100,6 +100,7 @@
287F3C6C246F90300040E76F /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 287F3C6B246F90300040E76F /* QuartzCore.framework */; };
28B962A52B6AF44F00ACCD96 /* UndoHistory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28B962A32B6AF44F00ACCD96 /* UndoHistory.cxx */; };
28B962A62B6AF44F00ACCD96 /* UndoHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = 28B962A42B6AF44F00ACCD96 /* UndoHistory.h */; };
+ 28CC23042C6F10F300D75568 /* DictionaryForCF.h in Headers */ = {isa = PBXBuildFile; fileRef = 28CC23032C6F10F300D75568 /* DictionaryForCF.h */; };
28EA9CAE255894B4007710C4 /* CharacterCategoryMap.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28EA9CAA255894B4007710C4 /* CharacterCategoryMap.cxx */; };
28EA9CAF255894B4007710C4 /* CharacterType.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28EA9CAB255894B4007710C4 /* CharacterType.cxx */; };
28EA9CB0255894B4007710C4 /* CharacterCategoryMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 28EA9CAC255894B4007710C4 /* CharacterCategoryMap.h */; };
@@ -203,6 +204,7 @@
287F3E0F246F9AE50040E76F /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = SOURCE_ROOT; };
28B962A32B6AF44F00ACCD96 /* UndoHistory.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UndoHistory.cxx; path = ../../src/UndoHistory.cxx; sourceTree = "<group>"; };
28B962A42B6AF44F00ACCD96 /* UndoHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UndoHistory.h; path = ../../src/UndoHistory.h; sourceTree = "<group>"; };
+ 28CC23032C6F10F300D75568 /* DictionaryForCF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DictionaryForCF.h; path = ../DictionaryForCF.h; sourceTree = "<group>"; };
28EA9CAA255894B4007710C4 /* CharacterCategoryMap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharacterCategoryMap.cxx; path = ../../src/CharacterCategoryMap.cxx; sourceTree = "<group>"; };
28EA9CAB255894B4007710C4 /* CharacterType.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharacterType.cxx; path = ../../src/CharacterType.cxx; sourceTree = "<group>"; };
28EA9CAC255894B4007710C4 /* CharacterCategoryMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CharacterCategoryMap.h; path = ../../src/CharacterCategoryMap.h; sourceTree = "<group>"; };
@@ -327,6 +329,7 @@
287F3C4E246F8E560040E76F /* Classes */ = {
isa = PBXGroup;
children = (
+ 28CC23032C6F10F300D75568 /* DictionaryForCF.h */,
282936DA24E2D55D00C84BA2 /* InfoBar.h */,
282936D424E2D55D00C84BA2 /* InfoBar.mm */,
282936D924E2D55D00C84BA2 /* InfoBarCommunicator.h */,
@@ -416,6 +419,7 @@
2829373B24E2D58800C84BA2 /* Position.h in Headers */,
282936E224E2D55D00C84BA2 /* ScintillaCocoa.h in Headers */,
2829373524E2D58800C84BA2 /* Style.h in Headers */,
+ 28CC23042C6F10F300D75568 /* DictionaryForCF.h in Headers */,
282936E424E2D55D00C84BA2 /* PlatCocoa.h in Headers */,
2807B4EB28964CA40063A31A /* ChangeHistory.h in Headers */,
2829376C24E2D58800C84BA2 /* Selection.h in Headers */,
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index 67795148c..0f0d7911f 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -609,6 +609,9 @@
<li>
Fix bug on Cocoa where double-click stopped working when system had been running for a long time.
</li>
+ <li>
+ On Cocoa implement more values of font weight and stretch.
+ </li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla551.zip">Release 5.5.1</a>