17 #include <Availability.h> 30 #ifdef MAC_OS_X_VERSION_10_11 38 const CTFontOrientation defaultFontOrientation = kCTFontDefaultOrientation;
39 const CTFontOrientation horizontalFontOrientation = kCTFontHorizontalOrientation;
40 const CTFontOrientation verticalFontOrientation = kCTFontVerticalOrientation;
49 if (
const TColor *
const color =
gROOT->GetColor(colorIndex)) {
50 color->GetRGB(r, g, b);
51 a = color->GetAlpha();
56 CGRect BBoxForCTRun(CTFontRef font, CTRunRef
run)
58 assert(font != 0 &&
"BBoxForCTRun, parameter 'font' is null");
59 assert(run != 0 &&
"BBoxForCTRun, parameter 'run' is null");
62 if (
const CFIndex nGlyphs = CTRunGetGlyphCount(run)) {
63 std::vector<CGGlyph> glyphs(nGlyphs);
64 CTRunGetGlyphs(run, CFRangeMake(0, 0), &glyphs[0]);
65 bbox = CTFontGetBoundingRectsForGlyphs(font, defaultFontOrientation,
66 &glyphs[0], 0, nGlyphs);
82 CFStringRef keys[] = {kCTFontAttributeName};
83 CFTypeRef values[] = {font};
85 Init(textLine, 1, keys, values);
97 CFStringRef keys[] = {kCTFontAttributeName};
98 CFTypeRef values[] = {font};
100 Init(unichars, 1, keys, values);
113 const CFScopeGuard<CGColorSpaceRef> rgbColorSpace(CGColorSpaceCreateDeviceRGB());
114 if (!rgbColorSpace.Get())
115 throw std::runtime_error(
"TextLine: color space");
117 Float_t rgba[] = {0.f, 0.f, 0.f, 1.f};
118 GetTextColorForIndex(color, rgba[0], rgba[1], rgba[2], rgba[3]);
119 const CGFloat cgRgba[] = {rgba[0], rgba[1], rgba[2], rgba[3]};
121 const CFScopeGuard<CGColorRef> textColor(CGColorCreate(rgbColorSpace.Get(), cgRgba));
124 CFStringRef keys[] = {kCTFontAttributeName, kCTForegroundColorAttributeName};
125 CFTypeRef values[] = {font, textColor.Get()};
127 Init(textLine, 2, keys, values);
139 CFScopeGuard<CGColorSpaceRef> rgbColorSpace(CGColorSpaceCreateDeviceRGB());
141 if (!rgbColorSpace.Get())
142 throw std::runtime_error(
"TexLine: color space is null");
144 CFScopeGuard<CGColorRef> textColor(CGColorCreate(rgbColorSpace.Get(), rgb));
147 CFStringRef keys[] = {kCTFontAttributeName, kCTForegroundColorAttributeName};
148 CFTypeRef values[] = {font, textColor.Get()};
150 Init(textLine, 2, keys, values);
164 const CFScopeGuard<CGColorSpaceRef> rgbColorSpace(CGColorSpaceCreateDeviceRGB());
165 if (!rgbColorSpace.Get())
166 throw std::runtime_error(
"TextLine: color space");
168 Float_t rgba[] = {0.f, 0.f, 0.f, 1.f};
169 GetTextColorForIndex(color, rgba[0], rgba[1], rgba[2], rgba[3]);
170 const CGFloat cgRgba[] = {rgba[0], rgba[1], rgba[2], rgba[3]};
172 const CFScopeGuard<CGColorRef> textColor(CGColorCreate(rgbColorSpace.Get(), cgRgba));
175 CFStringRef keys[] = {kCTFontAttributeName, kCTForegroundColorAttributeName};
176 CFTypeRef values[] = {font, textColor.Get()};
178 Init(unichars, 2, keys, values);
193 CGFloat ascent = 0., descent = 0., leading = 0.;
194 w =
UInt_t(CTLineGetTypographicBounds(
fCTLine, &ascent, &descent, &leading));
203 CGFloat ascent = 0., descent = 0., leading = 0.;
204 CTLineGetTypographicBounds(
fCTLine, &ascent, &descent, &leading);
206 desc =
Int_t(descent);
210 CFArrayRef runs = CTLineGetGlyphRuns(
fCTLine);
211 if (runs && CFArrayGetCount(runs) &&
fCTFont) {
212 CTRunRef firstRun =
static_cast<CTRunRef
>(CFArrayGetValueAtIndex(runs, 0));
214 if (CGRectIsNull(box))
217 for (CFIndex i = 1,
e = CFArrayGetCount(runs); i <
e; ++i) {
218 CTRunRef
run =
static_cast<CTRunRef
>(CFArrayGetValueAtIndex(runs, i));
219 CGRect nextBox = BBoxForCTRun(
fCTFont, run);
220 if (CGRectIsNull(nextBox))
222 box = CGRectUnion(box, nextBox);
237 const CFScopeGuard<CFDictionaryRef> stringAttribs(CFDictionaryCreate(kCFAllocatorDefault, (
const void **)keys, (
const void **)values,
238 nAttribs, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
239 if (!stringAttribs.Get())
240 throw std::runtime_error(
"TextLine: null attribs");
242 const CFScopeGuard<CFStringRef> wrappedCString(CFStringCreateWithCString(kCFAllocatorDefault, textLine, kCFStringEncodingMacRoman));
243 if (!wrappedCString.Get())
244 throw std::runtime_error(
"TextLine: cstr wrapper");
246 CFScopeGuard<CFAttributedStringRef> attributedString(CFAttributedStringCreate(kCFAllocatorDefault,
247 wrappedCString.Get(), stringAttribs.Get()));
248 fCTLine = CTLineCreateWithAttributedString(attributedString.Get());
251 throw std::runtime_error(
"TextLine: attrib string");
255 void TextLine::Init(
const std::vector<UniChar> &unichars,
UInt_t nAttribs, CFStringRef *keys, CFTypeRef *values)
259 const CFScopeGuard<CFStringRef> wrappedUniString(CFStringCreateWithCharacters(kCFAllocatorDefault, &unichars[0], unichars.size()));
260 const CFScopeGuard<CFDictionaryRef> stringAttribs(CFDictionaryCreate(kCFAllocatorDefault, (
const void **)keys, (
const void **)values,
261 nAttribs, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
263 if (!stringAttribs.Get())
264 throw std::runtime_error(
"TextLine: null attribs");
266 if (!wrappedUniString.Get())
267 throw std::runtime_error(
"TextLine: cstr wrapper");
269 const CFScopeGuard<CFAttributedStringRef> attributedString(CFAttributedStringCreate(kCFAllocatorDefault,
270 wrappedUniString.Get(), stringAttribs.Get()));
271 fCTLine = CTLineCreateWithAttributedString(attributedString.Get());
274 throw std::runtime_error(
"TextLine: attrib string");
280 assert(ctx != 0 &&
"DrawLine, ctx parameter is null");
288 assert(ctx != 0 &&
"DrawLine, ctx parameter is null");
290 CGContextSetAllowsAntialiasing(ctx, 1);
320 CGContextSetTextPosition(ctx, 0., 0.);
321 CGContextTranslateCTM(ctx, x, y);
323 CGContextTranslateCTM(ctx, xc, yc);
324 CGContextTranslateCTM(ctx, -0.5 * w, -0.5 *
h);
332 typedef std::vector<CGSize>::size_type size_type;
337 assert(ctx != 0 &&
"DrawTextLineNoKerning, ctx parameter is null");
338 assert(font != 0 &&
"DrawTextLineNoKerning, font parameter is null");
339 assert(text.size() &&
"DrawTextLineNoKerning, text parameter is an empty vector");
341 std::vector<CGGlyph> glyphs(text.size());
342 if (!CTFontGetGlyphsForCharacters(font, &text[0], &glyphs[0], text.size())) {
343 ::Error(
"DrawTextLineNoKerning",
"Font could not encode all Unicode characters in a text");
347 std::vector<CGSize> glyphAdvances(glyphs.size());
348 CTFontGetAdvancesForGlyphs(font, horizontalFontOrientation, &glyphs[0], &glyphAdvances[0], glyphs.size());
350 CGFloat currentX =
x;
351 std::vector<CGPoint> glyphPositions(glyphs.size());
352 glyphPositions[0].x = currentX;
353 glyphPositions[0].y =
y;
355 for (size_type i = 1; i < glyphs.size(); ++i) {
356 currentX +=
std::ceil(glyphAdvances[i - 1].width);
357 glyphPositions[i].x = currentX;
358 glyphPositions[i].y =
y;
361 CTFontDrawGlyphs(font, &glyphs[0], &glyphPositions[0], glyphs.size(), ctx);
void GetAscentDescent(Int_t &asc, Int_t &desc) const
Double_t Floor(Double_t x)
void GetBounds(UInt_t &w, UInt_t &h) const
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
const CTFontOrientation horizontalFontOrientation
const CTFontOrientation defaultFontOrientation
void run(bool only_compile=false)
TextLine(const char *textLine, CTFontRef font)
const CTFontOrientation verticalFontOrientation
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
The color creation and management class.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Double_t Ceil(Double_t x)
void DrawLine(CGContextRef ctx) const
void DrawTextLineNoKerning(CGContextRef ctx, CTFontRef font, const std::vector< UniChar > &text, Int_t x, Int_t y)
void Init(const char *textLine, UInt_t nAttribs, CFStringRef *keys, CFTypeRef *values)
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.