Skip to content

Commit

Permalink
#AeCairoTextToGlyphShaping show how to draw text taking into account …
Browse files Browse the repository at this point in the history
…clusters
  • Loading branch information
tinchodias committed Nov 22, 2023
1 parent 379e1bf commit e99b5cb
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 9 deletions.
7 changes: 7 additions & 0 deletions src/Alexandrie-Cairo/AeCairoExternalArray.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,16 @@ AeCairoExternalArray class >> fromHandle: aHandle size: aNumber [
{ #category : #'class initialization' }
AeCairoExternalArray class >> initialize [

self isAbstract ifTrue: [ ^self ].
resolvedType := self resolveType: self type
]

{ #category : #testing }
AeCairoExternalArray class >> isAbstract [

^ self == AeCairoExternalArray
]

{ #category : #'instance creation' }
AeCairoExternalArray class >> newFrom: anArrayedCollection [

Expand Down
4 changes: 2 additions & 2 deletions src/Alexandrie-Cairo/AeCairoGlyph.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ AeCairoGlyph >> printShortOn: aStream [

aStream
nextPutAll: '(';
print: self position;
nextPutAll: ' -> ';
print: self index;
nextPutAll: ': ';
print: self position;
nextPut: $)
]

Expand Down
18 changes: 18 additions & 0 deletions src/Alexandrie-Cairo/AeCairoTextCluster.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,21 @@ AeCairoTextCluster >> glyphCount: anObject [
"This method was automatically generated"
handle signedLongAt: OFFSET_GLYPHCOUNT put: anObject
]

{ #category : #printing }
AeCairoTextCluster >> printOn: aStream [

super printOn: aStream.
self printShortOn: aStream
]

{ #category : #printing }
AeCairoTextCluster >> printShortOn: aStream [

aStream
nextPut: $(;
print: self byteCount;
nextPutAll: ' ';
print: self glyphCount;
nextPut: $)
]
99 changes: 92 additions & 7 deletions src/Alexandrie-Cairo/AeCairoTextToGlyphShaping.class.st
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Class {
#name : #AeCairoTextToGlyphShaping,
#superclass : #Object,
#traits : 'AeTCairoLibrary',
#classTraits : 'AeTCairoLibrary classTrait',
#instVars : [
'scaledFont',
'x',
Expand All @@ -17,6 +19,45 @@ Class {
#category : #'Alexandrie-Cairo-Text'
}

{ #category : #examples }
AeCairoTextToGlyphShaping class >> exampleShapeAndDraw [

| fontSize string surfaceSize aSurface aContext aFTLibrary aFTFace aScaledFont aShaping aStatus |
fontSize := 12.
"Get Lorem Ipsum without last cr character"
string := (String loremIpsum: 28) allButLast.
surfaceSize := 150 @ (fontSize*1.3).
aSurface := AeCairoImageSurface
extent: surfaceSize
format: AeCairoSurfaceFormat argb32.
aContext := aSurface newContext.

"Set up scaled font in the context"
aFTLibrary := AeFTLibrary newInitialized.
aFTFace := AeSourceSansPro_Regular firstFaceUsing: aFTLibrary.
aContext
fontFace: (AeCairoFreetypeFontFace newForFace: aFTFace);
fontSize: fontSize.
aScaledFont := aContext scaledFont.

aShaping := AeCairoTextToGlyphShaping new.
aShaping string: string.
aShaping scaledFont: aScaledFont.
aStatus := aShaping convertTextToGlyphs.
aStatus ensureIsSuccess.
" aShaping newGlyphArray.
aShaping newClusterArray."

aContext
translateByX: 5 y: fontSize;
sourceColor: Color blue;
scaledFont: aScaledFont.

aShaping showTextGlyphsOn: aContext.

^ aSurface inspect
]

{ #category : #private }
AeCairoTextToGlyphShaping >> convertTextToGlyphs [
"Convert UTF-8 text to an array of glyphs. Return `CAIRO_STATUS_SUCCESS` upon success, or an error status if the input values are wrong or if conversion failed.
Expand Down Expand Up @@ -49,9 +90,53 @@ AeCairoTextToGlyphShaping >> initialize [

x := y := 0.0.

clusters := nil.
clusterCount := nil.
clusterFlags := nil.
glyphs := ExternalAddress new.
glyphCount := FFIInt32 newBuffer.

clusters := ExternalAddress new.
clusterCount := FFIInt32 newBuffer.
clusterFlags := FFIInt32 newBuffer.
]

{ #category : #API }
AeCairoTextToGlyphShaping >> newClusterArray [
"Precondition: convertTextToGlyphs"

| clusterArray |
clusterCount := clusterCount signedLongAt: 1.
clusterArray := clusterCount isZero
ifTrue: [
AeCairoTextClusterArray unownedNewOf: 0 ]
ifFalse: [
AeCairoTextClusterArray
fromHandle: clusters
size: clusterCount ].

"In both cases we must take care of freeing the array."
clusterArray autoRelease.

^ clusterArray
]

{ #category : #API }
AeCairoTextToGlyphShaping >> newGlyphArray [
"Precondition: convertTextToGlyphs"

| glyphArray |
"Cairo returns NULL pointer when no glyphs, so needs special treatment."
glyphCount := glyphCount signedLongAt: 1.
glyphArray := glyphCount isZero
ifTrue: [
AeCairoGlyphArray unownedNewOf: 0 ]
ifFalse: [
AeCairoGlyphArray
fromHandle: glyphs
size: glyphCount ].

"In both cases we must take care of freeing the array."
glyphArray autoRelease.

^ glyphArray
]

{ #category : #API }
Expand All @@ -67,11 +152,11 @@ AeCairoTextToGlyphShaping >> newGlyphArrayByConvertingText [
ifTrue: [
AeCairoGlyphArray unownedNewOf: 0 ]
ifFalse: [
AeCairoOpaqueGlyphArray
AeCairoGlyphArray
fromHandle: glyphs
size: glyphCount ].

"In both cases we must to take care of freeing the array."
"In both cases we must take care of freeing the array."
glyphArray autoRelease.

^ glyphArray
Expand Down Expand Up @@ -100,9 +185,9 @@ AeCairoTextToGlyphShaping >> showTextGlyphsOn: cairoContext [
int utf8ByteCount,
void *glyphs,
int glyphCount,
const cairo_text_cluster_t *clusters,
void *clusters,
int clusterCount,
cairo_text_cluster_flags_t clusterFlags
int clusterFlags
) )
]

Expand Down

0 comments on commit e99b5cb

Please sign in to comment.