SlideShare a Scribd company logo
1 of 38
Download to read offline
Text layout with Core Text
Jjgod Jiang <gzjjgod@gmail.com>
What is text layout?
 Convert a large piece of text into glyphs, and position
 them into correct place.
 Simple explanation: “Width in, heights out.”
 Input: text (in Unicode), font (platform dependent or
 independent), box (or other shapes), line height, tab
 width, etc.
 Output: glyphs (in glyph index of a specific font), origin
 points in the box
What is Core Text?
Mac OS X text layout framework in Core Foundation (C)
API
Existed since Tiger, used as private framework for
Cocoa and Apple apps
Publicly available since Leopard
No visible changes in Snow Leopard (There could be
more Cocoa text system stuff transition to Core Text)
Why Core Text?
A tale of two Apples
 The original Apple development team created “Classic”
 APIs like QuickDraw and MLTE
 The NeXT team created NS* APIs which we later called
 “Cocoa”
 Since the merge of the two company, solutions like
 Carbon and Quartz were created to close the gap
 For modern, Unicode-aware text layout, there is ATSUI,
 which is still a popular choice for now
More about ATSUI
Short for “Apple Type Services for Unicode Imaging”
Carbon like API (OSErr, Fixed, Pascal String, etc.)
Fast, robust, powerful, but the API is a bit complicate
to use
(Story: it took me a week to fix the original ATSUI-
based implementation in Vim, but only one day to
create a Core Text based one in vim-cocoa)
ATS (for font enumeration and selection) still exists, but
ATSUI is now almost deprecated, no 64-bit support
Core Text was created to
replace ATSUI.
Why Core Text (again)?
Simpler, Core Foundation style API, much easier to call
from Cocoa apps
Minimize conversion between different data formats,
improve performance (up to 2 times faster according to
Apple)
Supported behavior (like font traits) closely matches
with Cocoa Text System
Do I need Core Text?
Use APIs as high level as possible
Courtesy of http://xkcd.com/353/
Use APIs as high level as
possible
 Read the “Text” section of Cocoa Drawing Guide
 Use NSString/NSAttributedString or create a
 NSTextField for simple drawing in UI

 For more sophisticated text, the best (and easiest)
 choice is to use high level control like NSTextView or
 WebView. They are well optimized.

 If the function is too limited, try Cocoa Text System,
 utilize its low level plumbers (NSLayoutManager,
 NSTypesetter, NSTextContainer, etc.)
If none of the above work
well enough...
Case study: Textus
URL: http://www.jjgod.org/projects/textus
Icon courtesy of: chumsdock@newsmth
Case study: Textus
Aim to be a fast, lightweight (plain text) ebook reader.
WebView is too heavyweight for our purpose. So I went
for NSTextView, customize NSTypesetter,
NSTextContainer to control the output.
Cocoa Text System sometimes is just too
unpredictable, produces inconsistent results.
Took me two weekends to rewrote it with Core Text,
the most complex Core Text project I’ve ever done.
Learn Core Text:
Prerequisites
 You need some basic understanding on Core
 Foundation, CFString, CFDictionary, memory
 management, etc.
 You also need some knowledge on Core Graphics,
 CGPoint, CGRect, CGPath, CGGlyph, etc. Notice: most
 CG-structs are not interchangeable with their NS-
 correspondence.
 Since we all use Cocoa now, basic knowledge on
 NSView and Cocoa drawing context is needed.
Learn Core Text:
Getting Started
1. Create a new Cocoa Application project
called “CoreTextTest” in Xcode.
2. In Xcode, create a new class called
“CTView”, make it inherit from NSView.
3. Open MainMenu.xib, drag a NSView to
the empty window, in Identity panel, set its
class to “CTView”.
4. Then you can start your Core Text programming in
-drawRect: of CTView, check the result every time you
launch it.
Text Layout with Core Text:
Step by step
Basic Concepts
Every time you try to layout some text, your input is a
CFAttributedString and a CGPath, which describe
the text, parameters to layout, and the area containing
the resulting output.

          CTLine

           CTRun                               CGGlyph


          CTLine

                                    CTFrame
Step 1: Prepare Attributed
String
  First, you prepare a CFAttributedString with all the
  parameters set (to the whole string or part of the
  string):
NSAttributedString *str = [[NSAttributedString alloc]
    initWithString: @"We hold this truth..."
        attributes: [NSDictionary
    dictionaryWithObjectsAndKeys:
        [NSFont fontWithName: @"Helvetica" size: 12.0],
        (NSString *) kCTFontAttributeName]];

CFAttributedStringRef attrString =
    (CFAttributedStringRef) str;
Step 2: Create a
CTFramesetter
  Now you can create the central object for Core Text
  typesetting: CTFramesetter, you will use it through the
  entire layout process:

CTFramesetterRef framesetter =
    CTFramesetterCreateWithAttributedString(attrString);
Step 3: Create a CGPath
Third, you add one or more CGRect (or other shapes) to
form a complete CGPath:

CGMutablePathRef path = CGPathCreateMutable();

CGRect bounds = CGRectMake(10.0, 10.0, 200.0, 200.0);

CGPathAddRect(path, NULL, bounds);
Step 4: Get the frame!
 Use the CGPath and CTFramesetter to create
 CTFrame (s), then draw it in current context!


CTFrameRef frame =
    CTFramesetterCreateFrame(framesetter,
                             CFRangeMake(0, 0),
                             path, NULL);

CTFrameDraw(frame, context);
Step 5: Don’t forget to
release them
 Release everything you created with CFRelease.


CFRelease(attrString);
CFRelease(framesetter);
CFRelease(frame);
CFRelease(path);
Learn Core Text:
Techniques and Gotchas
Text Matrix
 Always remember to reset the text matrix before
 drawing, otherwise the result will be totally
 unpredictable, like using uninitialized memory:
 CGContextSetTextMatrix(context, CGAffineTransformIdentity);

 How to draw the text from top to bottom? use a up-
 side-down transform:
 CGContextSetTextMatrix(context,
                        CGAffineTransformMakeScale(1, -1));
Breaking layout into parts (1)
 Reading files into CFAttributedString is fast, but
 laying out them is much slower, but you don’t need to
 layout them all at once!
 Set a fixed rectangle for the CGPath, say, one or two
 pages, and initialize a range to create the CTFrame
 Each time a CTFrame is created, you can get the text
 range within this frame with
 CTFrameGetVisibleStringRange(frame)
Breaking layout into parts (2)
 Update the range for text not typesetted yet, continue
 creating CTFrames until there is no more
 Release the CTFrames each time you finish drawing
 them
Breaking layout (code)
CFRange fullRange = CFRangeMake(0, text.length);
CGRect frameRect = CGRectMake(0, 0, 100, 1000);
for (range = frameRange = CFRangeMake(0, 0);
     range.location < fullRange.length;
     range.location += frameRange.length)
{
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, frameRect);
    CTFrameRef frame =
        CTFramesetterCreateFrame(framesetter,
                                 range, path, NULL);
    CTFrameDraw(frame);
    frameRange = CTFrameGetVisibleStringRange(frame);
    frameRect.origin.y += frameRect.size.height;

    CFRelease(path);
    CFRelease(frame);
}
Flipped drawing (1)
 Cocoa (and Core Graphics) used a PostScript-like, up-
 side-down drawing model, (0, 0) is at bottom left.
 It is extremely inconvenient for text layout, because you
 can’t tell the y coordinates until you know the
 maximum height, but you don’t know the height until all
 the text is typesetted
 The coordinates associated CTFrame is up-side-down,
 so we need to break frame into CTLines with
 CTFrameGetLines(frame)
Flipped drawing (2)
 Retrieve the origins with CTFrameGetLineOrigins
 (frame)

 Calculate the line origin with coordinates flipped back
 Move to calculated coordinates, draw each line with
 CTLineDraw(line)
Flipped Drawing (code)
CFArrayRef lines = CTFrameGetLines(frame);
CFIndex i, total = CFArrayGetCount(lines);
CGFloat y;
CTFrameGetLineOrigins(frame,
                      CFRangeMake(0, total), origins);

for (i = 0; i < total; i++)
{
    CTLineRef line =
        (CTLineRef) CFArrayGetValueAtIndex(lines, i);
    y = frameRect.origin.y +
        frameRect.size.height - origins[i].y;
    CGContextSetTextPosition(context,
                              frameRect.origin.x +
                              origins[i].x, y);
    CTLineDraw(line, context)
}
Reference Reading
“Core Text Programming Guide” from Apple is a must
read
Core Text session video/slides in WWDC 2008
Text Rendering: an Excursion:
http://jjgod.org/docs/slides/text-rendering-tech.pdf
State of Text Rendering:
http://behdad.org/text/
Reference Codes
Core Text sample code from Apple
A step by step tutorial.
Textus: http://github.com/jjgod/textus
Complete demo of multipart layout and flipped drawing
Neuro: http://github.com/ishikawa/neuro
Vertical layout and text editing support.
vim-cocoa: http://github.com/jjgod/vim-cocoa
Low-level drawing with CTLine and CGGlyph.
That’s all. Thanks.

More Related Content

What's hot (20)

PHP
PHPPHP
PHP
 
Html Ppt
Html PptHtml Ppt
Html Ppt
 
Preprocessors
PreprocessorsPreprocessors
Preprocessors
 
Web Page Designing Using HTML
Web Page Designing Using HTMLWeb Page Designing Using HTML
Web Page Designing Using HTML
 
Web Development using HTML & CSS
Web Development using HTML & CSSWeb Development using HTML & CSS
Web Development using HTML & CSS
 
Mysql creating stored function
Mysql  creating stored function Mysql  creating stored function
Mysql creating stored function
 
Knowledge Sharing : Java Servlet
Knowledge Sharing : Java ServletKnowledge Sharing : Java Servlet
Knowledge Sharing : Java Servlet
 
Elements of programming
Elements of programmingElements of programming
Elements of programming
 
Basic Html Notes
Basic Html NotesBasic Html Notes
Basic Html Notes
 
standard template library(STL) in C++
standard template library(STL) in C++standard template library(STL) in C++
standard template library(STL) in C++
 
Structures and Pointers
Structures and PointersStructures and Pointers
Structures and Pointers
 
WEB PAGE DESIGN USING HTML
WEB PAGE DESIGN USING HTMLWEB PAGE DESIGN USING HTML
WEB PAGE DESIGN USING HTML
 
Exception handling and templates
Exception handling and templatesException handling and templates
Exception handling and templates
 
Intr To Html & Xhtml
Intr To Html & XhtmlIntr To Html & Xhtml
Intr To Html & Xhtml
 
1. introduction to html5
1. introduction to html51. introduction to html5
1. introduction to html5
 
c-programming-using-pointers
c-programming-using-pointersc-programming-using-pointers
c-programming-using-pointers
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
 
Debugging in visual studio (basic level)
Debugging in visual studio (basic level)Debugging in visual studio (basic level)
Debugging in visual studio (basic level)
 
Introduction to programming with c,
Introduction to programming with c,Introduction to programming with c,
Introduction to programming with c,
 
Java swing
Java swingJava swing
Java swing
 

Viewers also liked

Core Text: раскрываем интерактивные возможности текста
Core Text: раскрываем интерактивные возможности текстаCore Text: раскрываем интерактивные возможности текста
Core Text: раскрываем интерактивные возможности текстаAny Void
 
Введение в Core Text
Введение в Core TextВведение в Core Text
Введение в Core TextOleg Poyaganov
 
10 вещей, которые «невозможно» сделать в iOS
10 вещей, которые «невозможно» сделать в iOS10 вещей, которые «невозможно» сделать в iOS
10 вещей, которые «невозможно» сделать в iOSAny Void
 
Хитрости и грабли iOS разработки
Хитрости и грабли iOS разработкиХитрости и грабли iOS разработки
Хитрости и грабли iOS разработкиAny Void
 
iOS 7. Новые концепции и новые средства
iOS 7. Новые концепции и новые средстваiOS 7. Новые концепции и новые средства
iOS 7. Новые концепции и новые средстваAny Void
 
Hi performance table views with QuartzCore and CoreText
Hi performance table views with QuartzCore and CoreTextHi performance table views with QuartzCore and CoreText
Hi performance table views with QuartzCore and CoreTextMugunth Kumar
 

Viewers also liked (8)

Core Text: раскрываем интерактивные возможности текста
Core Text: раскрываем интерактивные возможности текстаCore Text: раскрываем интерактивные возможности текста
Core Text: раскрываем интерактивные возможности текста
 
Введение в Core Text
Введение в Core TextВведение в Core Text
Введение в Core Text
 
10 вещей, которые «невозможно» сделать в iOS
10 вещей, которые «невозможно» сделать в iOS10 вещей, которые «невозможно» сделать в iOS
10 вещей, которые «невозможно» сделать в iOS
 
Core text
Core textCore text
Core text
 
Хитрости и грабли iOS разработки
Хитрости и грабли iOS разработкиХитрости и грабли iOS разработки
Хитрости и грабли iOS разработки
 
iOS 7. Новые концепции и новые средства
iOS 7. Новые концепции и новые средстваiOS 7. Новые концепции и новые средства
iOS 7. Новые концепции и новые средства
 
Hi performance table views with QuartzCore and CoreText
Hi performance table views with QuartzCore and CoreTextHi performance table views with QuartzCore and CoreText
Hi performance table views with QuartzCore and CoreText
 
iOSで縦書き
iOSで縦書きiOSで縦書き
iOSで縦書き
 

Similar to Text Layout With Core Text

Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020Pedro Veloso
 
Opensource gis development - part 3
Opensource gis development - part 3Opensource gis development - part 3
Opensource gis development - part 3Andrea Antonello
 
SmashingConf SF: Unlocking the Power of CSS Grid Layout
SmashingConf SF: Unlocking the Power of CSS Grid LayoutSmashingConf SF: Unlocking the Power of CSS Grid Layout
SmashingConf SF: Unlocking the Power of CSS Grid LayoutRachel Andrew
 
M|18 Ingesting Data with the New Bulk Data Adapters
M|18 Ingesting Data with the New Bulk Data AdaptersM|18 Ingesting Data with the New Bulk Data Adapters
M|18 Ingesting Data with the New Bulk Data AdaptersMariaDB plc
 
Getting started with ES6
Getting started with ES6Getting started with ES6
Getting started with ES6Nitay Neeman
 
Client Side Programming with Applet
Client Side Programming with AppletClient Side Programming with Applet
Client Side Programming with Appletbackdoor
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in goborderj
 
Console I/o & basics of array and strings.pptx
Console I/o & basics of array and strings.pptxConsole I/o & basics of array and strings.pptx
Console I/o & basics of array and strings.pptxPRASENJITMORE2
 
All Day Hey! Unlocking The Power of CSS Grid Layout
All Day Hey! Unlocking The Power of CSS Grid LayoutAll Day Hey! Unlocking The Power of CSS Grid Layout
All Day Hey! Unlocking The Power of CSS Grid LayoutRachel Andrew
 
Introduction to apache_cassandra_for_developers-lhg
Introduction to apache_cassandra_for_developers-lhgIntroduction to apache_cassandra_for_developers-lhg
Introduction to apache_cassandra_for_developers-lhgzznate
 
Graphics, Threads and HTTPConnections in MIDLets
Graphics, Threads and HTTPConnections in MIDLetsGraphics, Threads and HTTPConnections in MIDLets
Graphics, Threads and HTTPConnections in MIDLetsJussi Pohjolainen
 
"Optimization of a .NET application- is it simple ! / ?", Yevhen Tatarynov
"Optimization of a .NET application- is it simple ! / ?",  Yevhen Tatarynov"Optimization of a .NET application- is it simple ! / ?",  Yevhen Tatarynov
"Optimization of a .NET application- is it simple ! / ?", Yevhen TatarynovFwdays
 
Text field and textarea
Text field and textareaText field and textarea
Text field and textareamyrajendra
 
SimpleArray between Python and C++
SimpleArray between Python and C++SimpleArray between Python and C++
SimpleArray between Python and C++Yung-Yu Chen
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and BeyondComicSansMS
 
Quartz 2D with Swift 3
Quartz 2D with Swift 3Quartz 2D with Swift 3
Quartz 2D with Swift 3Bob McCune
 
Unlocking the Power of CSS Grid Layout
Unlocking the Power of CSS Grid LayoutUnlocking the Power of CSS Grid Layout
Unlocking the Power of CSS Grid LayoutRachel Andrew
 

Similar to Text Layout With Core Text (20)

Java fx & xtext
Java fx & xtextJava fx & xtext
Java fx & xtext
 
Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020
 
Treinamento Qt básico - aula II
Treinamento Qt básico - aula IITreinamento Qt básico - aula II
Treinamento Qt básico - aula II
 
Opensource gis development - part 3
Opensource gis development - part 3Opensource gis development - part 3
Opensource gis development - part 3
 
SmashingConf SF: Unlocking the Power of CSS Grid Layout
SmashingConf SF: Unlocking the Power of CSS Grid LayoutSmashingConf SF: Unlocking the Power of CSS Grid Layout
SmashingConf SF: Unlocking the Power of CSS Grid Layout
 
M|18 Ingesting Data with the New Bulk Data Adapters
M|18 Ingesting Data with the New Bulk Data AdaptersM|18 Ingesting Data with the New Bulk Data Adapters
M|18 Ingesting Data with the New Bulk Data Adapters
 
Getting started with ES6
Getting started with ES6Getting started with ES6
Getting started with ES6
 
Client Side Programming with Applet
Client Side Programming with AppletClient Side Programming with Applet
Client Side Programming with Applet
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in go
 
Console I/o & basics of array and strings.pptx
Console I/o & basics of array and strings.pptxConsole I/o & basics of array and strings.pptx
Console I/o & basics of array and strings.pptx
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
All Day Hey! Unlocking The Power of CSS Grid Layout
All Day Hey! Unlocking The Power of CSS Grid LayoutAll Day Hey! Unlocking The Power of CSS Grid Layout
All Day Hey! Unlocking The Power of CSS Grid Layout
 
Introduction to apache_cassandra_for_developers-lhg
Introduction to apache_cassandra_for_developers-lhgIntroduction to apache_cassandra_for_developers-lhg
Introduction to apache_cassandra_for_developers-lhg
 
Graphics, Threads and HTTPConnections in MIDLets
Graphics, Threads and HTTPConnections in MIDLetsGraphics, Threads and HTTPConnections in MIDLets
Graphics, Threads and HTTPConnections in MIDLets
 
"Optimization of a .NET application- is it simple ! / ?", Yevhen Tatarynov
"Optimization of a .NET application- is it simple ! / ?",  Yevhen Tatarynov"Optimization of a .NET application- is it simple ! / ?",  Yevhen Tatarynov
"Optimization of a .NET application- is it simple ! / ?", Yevhen Tatarynov
 
Text field and textarea
Text field and textareaText field and textarea
Text field and textarea
 
SimpleArray between Python and C++
SimpleArray between Python and C++SimpleArray between Python and C++
SimpleArray between Python and C++
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
 
Quartz 2D with Swift 3
Quartz 2D with Swift 3Quartz 2D with Swift 3
Quartz 2D with Swift 3
 
Unlocking the Power of CSS Grid Layout
Unlocking the Power of CSS Grid LayoutUnlocking the Power of CSS Grid Layout
Unlocking the Power of CSS Grid Layout
 

Recently uploaded

Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IES VE
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.YounusS2
 

Recently uploaded (20)

Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 

Text Layout With Core Text

  • 1. Text layout with Core Text Jjgod Jiang <gzjjgod@gmail.com>
  • 2. What is text layout? Convert a large piece of text into glyphs, and position them into correct place. Simple explanation: “Width in, heights out.” Input: text (in Unicode), font (platform dependent or independent), box (or other shapes), line height, tab width, etc. Output: glyphs (in glyph index of a specific font), origin points in the box
  • 3. What is Core Text? Mac OS X text layout framework in Core Foundation (C) API Existed since Tiger, used as private framework for Cocoa and Apple apps Publicly available since Leopard No visible changes in Snow Leopard (There could be more Cocoa text system stuff transition to Core Text)
  • 5. A tale of two Apples The original Apple development team created “Classic” APIs like QuickDraw and MLTE The NeXT team created NS* APIs which we later called “Cocoa” Since the merge of the two company, solutions like Carbon and Quartz were created to close the gap For modern, Unicode-aware text layout, there is ATSUI, which is still a popular choice for now
  • 6. More about ATSUI Short for “Apple Type Services for Unicode Imaging” Carbon like API (OSErr, Fixed, Pascal String, etc.) Fast, robust, powerful, but the API is a bit complicate to use (Story: it took me a week to fix the original ATSUI- based implementation in Vim, but only one day to create a Core Text based one in vim-cocoa) ATS (for font enumeration and selection) still exists, but ATSUI is now almost deprecated, no 64-bit support
  • 7. Core Text was created to replace ATSUI.
  • 8. Why Core Text (again)? Simpler, Core Foundation style API, much easier to call from Cocoa apps Minimize conversion between different data formats, improve performance (up to 2 times faster according to Apple) Supported behavior (like font traits) closely matches with Cocoa Text System
  • 9. Do I need Core Text?
  • 10. Use APIs as high level as possible Courtesy of http://xkcd.com/353/
  • 11. Use APIs as high level as possible Read the “Text” section of Cocoa Drawing Guide Use NSString/NSAttributedString or create a NSTextField for simple drawing in UI For more sophisticated text, the best (and easiest) choice is to use high level control like NSTextView or WebView. They are well optimized. If the function is too limited, try Cocoa Text System, utilize its low level plumbers (NSLayoutManager, NSTypesetter, NSTextContainer, etc.)
  • 12. If none of the above work well enough...
  • 13. Case study: Textus URL: http://www.jjgod.org/projects/textus Icon courtesy of: chumsdock@newsmth
  • 14. Case study: Textus Aim to be a fast, lightweight (plain text) ebook reader. WebView is too heavyweight for our purpose. So I went for NSTextView, customize NSTypesetter, NSTextContainer to control the output. Cocoa Text System sometimes is just too unpredictable, produces inconsistent results. Took me two weekends to rewrote it with Core Text, the most complex Core Text project I’ve ever done.
  • 15. Learn Core Text: Prerequisites You need some basic understanding on Core Foundation, CFString, CFDictionary, memory management, etc. You also need some knowledge on Core Graphics, CGPoint, CGRect, CGPath, CGGlyph, etc. Notice: most CG-structs are not interchangeable with their NS- correspondence. Since we all use Cocoa now, basic knowledge on NSView and Cocoa drawing context is needed.
  • 17. 1. Create a new Cocoa Application project called “CoreTextTest” in Xcode.
  • 18. 2. In Xcode, create a new class called “CTView”, make it inherit from NSView.
  • 19. 3. Open MainMenu.xib, drag a NSView to the empty window, in Identity panel, set its class to “CTView”.
  • 20. 4. Then you can start your Core Text programming in -drawRect: of CTView, check the result every time you launch it.
  • 21. Text Layout with Core Text: Step by step
  • 22. Basic Concepts Every time you try to layout some text, your input is a CFAttributedString and a CGPath, which describe the text, parameters to layout, and the area containing the resulting output. CTLine CTRun CGGlyph CTLine CTFrame
  • 23. Step 1: Prepare Attributed String First, you prepare a CFAttributedString with all the parameters set (to the whole string or part of the string): NSAttributedString *str = [[NSAttributedString alloc] initWithString: @"We hold this truth..." attributes: [NSDictionary dictionaryWithObjectsAndKeys: [NSFont fontWithName: @"Helvetica" size: 12.0], (NSString *) kCTFontAttributeName]]; CFAttributedStringRef attrString = (CFAttributedStringRef) str;
  • 24. Step 2: Create a CTFramesetter Now you can create the central object for Core Text typesetting: CTFramesetter, you will use it through the entire layout process: CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
  • 25. Step 3: Create a CGPath Third, you add one or more CGRect (or other shapes) to form a complete CGPath: CGMutablePathRef path = CGPathCreateMutable(); CGRect bounds = CGRectMake(10.0, 10.0, 200.0, 200.0); CGPathAddRect(path, NULL, bounds);
  • 26. Step 4: Get the frame! Use the CGPath and CTFramesetter to create CTFrame (s), then draw it in current context! CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL); CTFrameDraw(frame, context);
  • 27. Step 5: Don’t forget to release them Release everything you created with CFRelease. CFRelease(attrString); CFRelease(framesetter); CFRelease(frame); CFRelease(path);
  • 29. Text Matrix Always remember to reset the text matrix before drawing, otherwise the result will be totally unpredictable, like using uninitialized memory: CGContextSetTextMatrix(context, CGAffineTransformIdentity); How to draw the text from top to bottom? use a up- side-down transform: CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1, -1));
  • 30. Breaking layout into parts (1) Reading files into CFAttributedString is fast, but laying out them is much slower, but you don’t need to layout them all at once! Set a fixed rectangle for the CGPath, say, one or two pages, and initialize a range to create the CTFrame Each time a CTFrame is created, you can get the text range within this frame with CTFrameGetVisibleStringRange(frame)
  • 31. Breaking layout into parts (2) Update the range for text not typesetted yet, continue creating CTFrames until there is no more Release the CTFrames each time you finish drawing them
  • 32. Breaking layout (code) CFRange fullRange = CFRangeMake(0, text.length); CGRect frameRect = CGRectMake(0, 0, 100, 1000); for (range = frameRange = CFRangeMake(0, 0); range.location < fullRange.length; range.location += frameRange.length) { CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, NULL, frameRect); CTFrameRef frame = CTFramesetterCreateFrame(framesetter, range, path, NULL); CTFrameDraw(frame); frameRange = CTFrameGetVisibleStringRange(frame); frameRect.origin.y += frameRect.size.height; CFRelease(path); CFRelease(frame); }
  • 33. Flipped drawing (1) Cocoa (and Core Graphics) used a PostScript-like, up- side-down drawing model, (0, 0) is at bottom left. It is extremely inconvenient for text layout, because you can’t tell the y coordinates until you know the maximum height, but you don’t know the height until all the text is typesetted The coordinates associated CTFrame is up-side-down, so we need to break frame into CTLines with CTFrameGetLines(frame)
  • 34. Flipped drawing (2) Retrieve the origins with CTFrameGetLineOrigins (frame) Calculate the line origin with coordinates flipped back Move to calculated coordinates, draw each line with CTLineDraw(line)
  • 35. Flipped Drawing (code) CFArrayRef lines = CTFrameGetLines(frame); CFIndex i, total = CFArrayGetCount(lines); CGFloat y; CTFrameGetLineOrigins(frame, CFRangeMake(0, total), origins); for (i = 0; i < total; i++) { CTLineRef line = (CTLineRef) CFArrayGetValueAtIndex(lines, i); y = frameRect.origin.y + frameRect.size.height - origins[i].y; CGContextSetTextPosition(context, frameRect.origin.x + origins[i].x, y); CTLineDraw(line, context) }
  • 36. Reference Reading “Core Text Programming Guide” from Apple is a must read Core Text session video/slides in WWDC 2008 Text Rendering: an Excursion: http://jjgod.org/docs/slides/text-rendering-tech.pdf State of Text Rendering: http://behdad.org/text/
  • 37. Reference Codes Core Text sample code from Apple A step by step tutorial. Textus: http://github.com/jjgod/textus Complete demo of multipart layout and flipped drawing Neuro: http://github.com/ishikawa/neuro Vertical layout and text editing support. vim-cocoa: http://github.com/jjgod/vim-cocoa Low-level drawing with CTLine and CGGlyph.