File: QuartzTextLayout.h

package info (click to toggle)
codequery 1.0.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,860 kB
  • sloc: cpp: 151,420; xml: 16,576; python: 5,602; ansic: 5,487; makefile: 559; perl: 496; ruby: 209; sql: 194; sh: 106; php: 53; vhdl: 51; erlang: 47; objc: 22; lisp: 18; cobol: 18; modula3: 17; asm: 14; fortran: 12; ml: 11; tcl: 6
file content (101 lines) | stat: -rw-r--r-- 2,478 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
 *  QuartzTextLayout.h
 *
 *  Original Code by Evan Jones on Wed Oct 02 2002.
 *  Contributors:
 *  Shane Caraveo, ActiveState
 *  Bernd Paradies, Adobe
 *
 */

#ifndef QUARTZTEXTLAYOUT_H
#define QUARTZTEXTLAYOUT_H

#include <Cocoa/Cocoa.h>

#include "QuartzTextStyle.h"


class QuartzTextLayout {
public:
	/** Create a text layout for drawing. */
	QuartzTextLayout(std::string_view sv, CFStringEncoding encoding, const QuartzTextStyle *r) {
		encodingUsed = encoding;
		const UInt8 *puiBuffer = reinterpret_cast<const UInt8 *>(sv.data());
		CFStringRef str = CFStringCreateWithBytes(NULL, puiBuffer, sv.length(), encodingUsed, false);
		if (!str) {
			// Failed to decode bytes into string with given encoding so try
			// MacRoman which should accept any byte.
			encodingUsed = kCFStringEncodingMacRoman;
			str = CFStringCreateWithBytes(NULL, puiBuffer, sv.length(), encodingUsed, false);
		}
		if (!str) {
			return;
		}

		stringLength = CFStringGetLength(str);

		CFMutableDictionaryRef stringAttribs = r->getCTStyle();

		mString = ::CFAttributedStringCreate(NULL, str, stringAttribs);

		mLine = ::CTLineCreateWithAttributedString(mString);

		CFRelease(str);
	}

	~QuartzTextLayout() {
		if (mString) {
			CFRelease(mString);
			mString = NULL;
		}
		if (mLine) {
			CFRelease(mLine);
			mLine = NULL;
		}
	}

	/** Draw the text layout into a CGContext at the specified position.
	* @param gc The CGContext in which to draw the text.
	* @param x The x axis position to draw the baseline in the current CGContext.
	* @param y The y axis position to draw the baseline in the current CGContext. */
	void draw(CGContextRef gc, double x, double y) {
		if (!mLine)
			return;

		::CGContextSetTextMatrix(gc, CGAffineTransformMakeScale(1.0, -1.0));

		// Set the text drawing position.
		::CGContextSetTextPosition(gc, x, y);

		// And finally, draw!
		::CTLineDraw(mLine, gc);
	}

	float MeasureStringWidth() {
		if (mLine == NULL)
			return 0.0f;

		return static_cast<float>(::CTLineGetTypographicBounds(mLine, NULL, NULL, NULL));
	}

	CTLineRef getCTLine() {
		return mLine;
	}

	CFIndex getStringLength() {
		return stringLength;
	}

	CFStringEncoding getEncoding() {
		return encodingUsed;
	}

private:
	CFAttributedStringRef mString = NULL;
	CTLineRef mLine = NULL;
	CFIndex stringLength = 0;
	CFStringEncoding encodingUsed = kCFStringEncodingMacRoman;
};

#endif