17#include <Availability.h>
30#ifdef MAC_OS_X_VERSION_10_11
50 color->GetRGB(
r,
g,
b);
51 a = color->GetAlpha();
56CGRect 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]);
66 &glyphs[0], 0, nGlyphs);
80 CFStringRef keys[] = {kCTFontAttributeName};
81 CFTypeRef values[] = {font};
83 Init(textLine, 1, keys, values);
93 CFStringRef keys[] = {kCTFontAttributeName};
94 CFTypeRef values[] = {font};
96 Init(unichars, 1, keys, values);
107 const CFScopeGuard<CGColorSpaceRef> rgbColorSpace(CGColorSpaceCreateDeviceRGB());
108 if (!rgbColorSpace.Get())
109 throw std::runtime_error(
"TextLine: color space");
111 Float_t rgba[] = {0.f, 0.f, 0.f, 1.f};
112 GetTextColorForIndex(color, rgba[0], rgba[1], rgba[2], rgba[3]);
113 const CGFloat cgRgba[] = {rgba[0], rgba[1], rgba[2], rgba[3]};
115 const CFScopeGuard<CGColorRef> textColor(CGColorCreate(rgbColorSpace.Get(), cgRgba));
118 CFStringRef keys[] = {kCTFontAttributeName, kCTForegroundColorAttributeName};
119 CFTypeRef values[] = {font, textColor.Get()};
121 Init(textLine, 2, keys, values);
131 CFScopeGuard<CGColorSpaceRef> rgbColorSpace(CGColorSpaceCreateDeviceRGB());
133 if (!rgbColorSpace.Get())
134 throw std::runtime_error(
"TexLine: color space is null");
136 CFScopeGuard<CGColorRef> textColor(CGColorCreate(rgbColorSpace.Get(), rgb));
139 CFStringRef keys[] = {kCTFontAttributeName, kCTForegroundColorAttributeName};
140 CFTypeRef values[] = {font, textColor.Get()};
142 Init(textLine, 2, keys, values);
153 const CFScopeGuard<CGColorSpaceRef> rgbColorSpace(CGColorSpaceCreateDeviceRGB());
154 if (!rgbColorSpace.Get())
155 throw std::runtime_error(
"TextLine: color space");
157 Float_t rgba[] = {0.f, 0.f, 0.f, 1.f};
158 GetTextColorForIndex(color, rgba[0], rgba[1], rgba[2], rgba[3]);
159 const CGFloat cgRgba[] = {rgba[0], rgba[1], rgba[2], rgba[3]};
161 const CFScopeGuard<CGColorRef> textColor(CGColorCreate(rgbColorSpace.Get(), cgRgba));
164 CFStringRef keys[] = {kCTFontAttributeName, kCTForegroundColorAttributeName};
165 CFTypeRef values[] = {font, textColor.Get()};
167 Init(unichars, 2, keys, values);
182 CGFloat ascent = 0., descent = 0., leading = 0.;
183 w =
UInt_t(CTLineGetTypographicBounds(
fCTLine, &ascent, &descent, &leading));
192 CGFloat ascent = 0., descent = 0., leading = 0.;
193 CTLineGetTypographicBounds(
fCTLine, &ascent, &descent, &leading);
195 desc =
Int_t(descent);
199 CFArrayRef runs = CTLineGetGlyphRuns(
fCTLine);
200 if (runs && CFArrayGetCount(runs) &&
fCTFont) {
201 CTRunRef firstRun =
static_cast<CTRunRef
>(CFArrayGetValueAtIndex(runs, 0));
203 if (CGRectIsNull(
box))
206 for (CFIndex i = 1,
e = CFArrayGetCount(runs); i <
e; ++i) {
207 CTRunRef run =
static_cast<CTRunRef
>(CFArrayGetValueAtIndex(runs, i));
208 CGRect nextBox = BBoxForCTRun(
fCTFont, run);
209 if (CGRectIsNull(nextBox))
211 box = CGRectUnion(
box, nextBox);
226 const CFScopeGuard<CFDictionaryRef> stringAttribs(CFDictionaryCreate(kCFAllocatorDefault, (
const void **)keys, (
const void **)values,
227 nAttribs, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
228 if (!stringAttribs.Get())
229 throw std::runtime_error(
"TextLine: null attribs");
231 const CFScopeGuard<CFStringRef> wrappedCString(CFStringCreateWithCString(kCFAllocatorDefault, textLine, kCFStringEncodingMacRoman));
232 if (!wrappedCString.Get())
233 throw std::runtime_error(
"TextLine: cstr wrapper");
235 CFScopeGuard<CFAttributedStringRef> attributedString(CFAttributedStringCreate(kCFAllocatorDefault,
236 wrappedCString.Get(), stringAttribs.Get()));
237 fCTLine = CTLineCreateWithAttributedString(attributedString.Get());
240 throw std::runtime_error(
"TextLine: attrib string");
244void TextLine::Init(
const std::vector<UniChar> &unichars,
UInt_t nAttribs, CFStringRef *keys, CFTypeRef *values)
248 const CFScopeGuard<CFStringRef> wrappedUniString(CFStringCreateWithCharacters(kCFAllocatorDefault, &unichars[0], unichars.size()));
249 const CFScopeGuard<CFDictionaryRef> stringAttribs(CFDictionaryCreate(kCFAllocatorDefault, (
const void **)keys, (
const void **)values,
250 nAttribs, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
252 if (!stringAttribs.Get())
253 throw std::runtime_error(
"TextLine: null attribs");
255 if (!wrappedUniString.Get())
256 throw std::runtime_error(
"TextLine: cstr wrapper");
258 const CFScopeGuard<CFAttributedStringRef> attributedString(CFAttributedStringCreate(kCFAllocatorDefault,
259 wrappedUniString.Get(), stringAttribs.Get()));
260 fCTLine = CTLineCreateWithAttributedString(attributedString.Get());
263 throw std::runtime_error(
"TextLine: attrib string");
269 assert(ctx != 0 &&
"DrawLine, ctx parameter is null");
277 assert(ctx != 0 &&
"DrawLine, ctx parameter is null");
279 CGContextSetAllowsAntialiasing(ctx, 1);
309 CGContextSetTextPosition(ctx, 0., 0.);
310 CGContextTranslateCTM(ctx,
x,
y);
312 CGContextTranslateCTM(ctx, xc, yc);
313 CGContextTranslateCTM(ctx, -0.5 *
w, -0.5 *
h);
321 typedef std::vector<CGSize>::size_type size_type;
326 assert(ctx != 0 &&
"DrawTextLineNoKerning, ctx parameter is null");
327 assert(font != 0 &&
"DrawTextLineNoKerning, font parameter is null");
328 assert(
text.size() &&
"DrawTextLineNoKerning, text parameter is an empty vector");
330 std::vector<CGGlyph> glyphs(
text.size());
331 if (!CTFontGetGlyphsForCharacters(font, &
text[0], &glyphs[0],
text.size())) {
332 ::Error(
"DrawTextLineNoKerning",
"Font could not encode all Unicode characters in a text");
336 std::vector<CGSize> glyphAdvances(glyphs.size());
339 CGFloat currentX =
x;
340 std::vector<CGPoint> glyphPositions(glyphs.size());
341 glyphPositions[0].x = currentX;
342 glyphPositions[0].y =
y;
344 for (size_type i = 1; i < glyphs.size(); ++i) {
345 currentX += std::ceil(glyphAdvances[i - 1].
width);
346 glyphPositions[i].x = currentX;
347 glyphPositions[i].y =
y;
350 CTFontDrawGlyphs(font, &glyphs[0], &glyphPositions[0], glyphs.size(), ctx);
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char DrawLine
Option_t Option_t TPoint TPoint const char text
void GetBounds(UInt_t &w, UInt_t &h) const
void GetAscentDescent(Int_t &asc, Int_t &desc) const
void Init(const char *textLine, UInt_t nAttribs, CFStringRef *keys, CFTypeRef *values)
TextLine(const char *textLine, CTFontRef font)
void DrawLine(CGContextRef ctx) const
The color creation and management class.
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
const CTFontOrientation defaultFontOrientation
void DrawTextLineNoKerning(CGContextRef ctx, CTFontRef font, const std::vector< UniChar > &text, Int_t x, Int_t y)
const CTFontOrientation horizontalFontOrientation
const CTFontOrientation verticalFontOrientation
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.