1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2024-12-27 03:48:21 +01:00

Add bootstrap font icons support

This commit is contained in:
Dany LE 2022-03-21 01:45:21 +01:00
parent ac764da076
commit eba462b9c0
12 changed files with 162 additions and 43 deletions

View File

@ -18,6 +18,11 @@ DiyaBaseObject >> logError: string [
self stderr nextPutAll: string; cr
]
{ #category : #asserting }
DiyaBaseObject >> shouldNotBeCalled [
^DiyaCoreAPIError signal: 'Should not be called'
]
{ #category : #accessing }
DiyaBaseObject >> stderr [
^VTermOutputDriver stderr

View File

@ -47,9 +47,7 @@ DiyaBoot >> bindGlobalEventTo: aNode [
pointer borderWidth: 3."
aNode on: #keydown do:[:e| Transcript show: 'keydown...';cr. running := false.].
aNode on: #quit do: [:e| running := false].
aNode on: #fingerdown do:[:e| self setCursorPosition: e mapped ].
aNode on: #fingermotion do:[:e| self setCursorPosition: e mapped ].
aNode on: #mousemotion do:[:e|
aNode on: #(fingerdown fingermotion mousemotion) do:[:e|
pointer position: e mapped worldPosition.
DiyaRendererContext uniqueInstance mouse: (e mapped x) @ (e mapped y).
].
@ -91,10 +89,10 @@ DiyaBoot >> createWindow [
{ #category : #events }
DiyaBoot >> exampleNodes: tree [
|root node node1 ell tex txtNode|
|root node node1 ell tex txtNode icon|
root := tree addNode: (Diya2DNode new) at: 0@10.
tex := (DiyaImageTex fromFile:Smalltalk imageDirectory / 'assets'/'mrsang.png').
txtNode := root addNode: (DiyaText data: 'Event') at: 10@50.
txtNode := root addNode: (DiyaText data: 'Event') at: 10@55.
txtNode color: Color orange.
txtNode extent: 200@40.
@ -102,7 +100,7 @@ DiyaBoot >> exampleNodes: tree [
node1 rotation: (Float pi / 8.0).
node1 scale: 1.2@1.2.
node1 on: #mousebuttondown do:[:e| txtNode data: 'Mouse ', (node1 local: e mapped worldPosition) asIntegerPoint asString].
node1 on: #fingerdown do:[:e| Transcript show:'finger down on image'; cr].
node1 on: #fingerdown do:[:e| txtNode data: 'Mouse ', (node1 local: e mapped worldPosition) asIntegerPoint asString].
node := root addNode: (DiyaRectangle size: 200@200) at: 250 @ 430.
node texture: tex.
@ -121,7 +119,7 @@ DiyaBoot >> exampleNodes: tree [
node := root addNode: (DiyaText data: String loremIpsum) at: 10@400.
node extent: 250@320.
node extent: 240@320.
node wordWrap: true.
node := root addNode: (DiyaLine from: 10@620 to: 200@635).
@ -137,7 +135,7 @@ DiyaBoot >> exampleNodes: tree [
"node rotation: Float pi / 2.0."
ell texture: tex.
ell on: #mousebuttondown do:[:e| txtNode data: 'Ellipse clicked', (ell local:e mapped worldPosition) asIntegerPoint asString].
ell on: #fingerdown do:[:e| Transcript show:'finger down on ellipse'; cr].
ell on: #fingerdown do:[:e| txtNode data: 'Ellipse clicked', (ell local:e mapped worldPosition) asIntegerPoint asString].
node := root addNode: (DiyaConvexPolygon points:{250@100. 400@250. 450@80. 350@60}).
@ -146,6 +144,9 @@ DiyaBoot >> exampleNodes: tree [
node texture: tex.
node borderWidth: 3.0.
icon := root addNode: (DiyaFontIcon data: #(16rF101 16rF155 16rF185 16rF21B 16rF298 16rF254)) at: 10@10.
icon fontSize: 24.
icon color: (Color r: 209/255 g: 66/255 b:245/255 ).
^ root
]

View File

@ -38,6 +38,11 @@ DiyaEllipse >> drawBorder [
"do nothing"
]
{ #category : #initialization }
DiyaEllipse >> drawLines [
self shouldNotBeCalled
]
{ #category : #initialization }
DiyaEllipse >> initialize [
super initialize.

View File

@ -0,0 +1,58 @@
Class {
#name : #DiyaFontIcon,
#superclass : #DiyaText,
#pools : [
'FT2Types'
],
#category : #'Diya-Graphics'
}
{ #category : #initialization }
DiyaFontIcon >> data: code [
super data:(code isArray ifTrue: [ code ] ifFalse:[{code}]).
bbox := Rectangle origin: 0@0 corner: ((data size) * (self fontSize) ) @ self fontSize.
]
{ #category : #initialization }
DiyaFontIcon >> drawText [
|index offset tex|
index := 1.
tex := self texture.
offset := 0@(self fontSize).
1 to: data size do: [ :i|
(self getCharsVerticesAt:i offset: offset on: tex) do: [
:e| vbuffer at: index put:e.
index := index + 1
].
"offset setX: offset x + tex spacing setY: offset y"
].
]
{ #category : #initialization }
DiyaFontIcon >> fontName: name style: face size: size [
super fontName: name style:face size: size.
data ifNil: [ ^ self ].
bbox := Rectangle origin: 0@0 corner: ((data size) * (self fontSize) ) @ self fontSize.
]
{ #category : #initialization }
DiyaFontIcon >> getLinebreakIndices: delta [
self shouldNotBeCalled
]
{ #category : #initialization }
DiyaFontIcon >> initialize [
super initialize.
data := { }.
self fontName: 'bootstrap-icons' style: 'Regular' size: 16.
vbuffer := FFIExternalArray externalNewType: GLfloat size:24.
vbuffer autoRelease.
style := DiyaFontManager uniqueInstance defaultIconSet.
]
{ #category : #initialization }
DiyaFontIcon >> lastSeparatorFrom: i [
self shouldNotBeCalled
]

View File

@ -25,6 +25,18 @@ DiyaFontManager >> defaultFamily [
^'Ubuntu'
]
{ #category : #initialization }
DiyaFontManager >> defaultIconSet [
^ self style: 'Regular' from: 'bootstrap-icons'
]
{ #category : #initialization }
DiyaFontManager >> defaultStyle [
^'Regular'
]
{ #category : #accessing }
@ -97,7 +109,7 @@ DiyaFontManager >> reset [
{ #category : #initialization }
DiyaFontManager >> style: styleName from: familyName [
|family|
family := families at: familyName ifAbsent: [ self defaultFamily ].
family := families at: familyName ifAbsent: [ families at: self defaultFamily ].
^family style: styleName
]

View File

@ -1,5 +0,0 @@
Class {
#name : #DiyaIcon,
#superclass : #DiyaImageView,
#category : #'Diya-Widgets'
}

View File

@ -53,6 +53,11 @@ DiyaLine >> drawBorder [
"do nothing"
]
{ #category : #initialization }
DiyaLine >> drawLines [
self shouldNotBeCalled
]
{ #category : #accessing }
DiyaLine >> from [
^ from

View File

@ -86,10 +86,8 @@ DiyaNode >> isRoot [
{ #category : #convenience }
DiyaNode >> on: eventName do: aBlock [
|evtCode|
evtCode := SDL2Constants bindingOf: ('SDL_', eventName asUppercase).
evtCode ifNil: [ ^DiyaCoreAPIError signal: 'Unknow event ', eventName ].
ehandlers at: evtCode value put: aBlock.
eventName isArray ifFalse:[ ^ self register: aBlock to: eventName ].
eventName do:[:e| self register: aBlock to:e ].
]
@ -114,6 +112,15 @@ DiyaNode >> position: anObject [
self updateTF.
]
{ #category : #convenience }
DiyaNode >> register: aBlock to: eventName [
|evtCode|
evtCode := SDL2Constants bindingOf: ('SDL_', eventName asUppercase).
evtCode ifNil: [ ^DiyaCoreAPIError signal: 'Unknow event ', eventName ].
ehandlers at: evtCode value put: aBlock.
]
{ #category : #accessing }
DiyaNode >> render [
dirty ifTrue:[dirty := self update not].

View File

@ -39,14 +39,21 @@ DiyaText >> data: anObject [
{ #category : #initialization }
DiyaText >> drawBorder [
self shouldNotBeCalled
]
{ #category : #initialization }
DiyaText >> drawLines [
^ self shouldNotBeCalled
]
{ #category : #accessing }
DiyaText >> drawText [
|vertices index tex2D offset|
|vertices index tex2D offset lbdelta|
index := 1.
offset := 0@0.
tex2D := self texture.
lbdelta := self getLinebreakIndices: (self extent x / tex2D meanww) asInteger.
1 to: data size do: [ :i|
vertices := self getCharsVerticesAt:i offset: offset on: tex2D.
vertices do: [
@ -54,8 +61,11 @@ DiyaText >> drawText [
index := index + 1.
].
(offset x > self extent x and: wrap not) ifTrue: [ ^self ].
((lbdelta includes: i + 1) and: wrap) ifTrue: [
offset setX: 0.0 setY: (offset y )- (tex2D linespace).
(offset y negated > self extent y) ifTrue: [ ^self ].
].
].
]
{ #category : #accessing }
@ -71,8 +81,12 @@ DiyaText >> fontName [
{ #category : #initialization }
DiyaText >> fontName: name style: face size: size [
name ifNotNil: [ fontName := name ].
face ifNotNil: [ fontStyle := face ].
name ifNotNil: [fontName := name].
face ifNotNil: [fontStyle := face].
fontName := fontName ifNil: [DiyaFontManager uniqueInstance defaultFamily].
fontStyle := fontStyle ifNil: [DiyaFontManager uniqueInstance defaultStyle].
fontSize := size.
style := DiyaFontManager uniqueInstance style: self fontStyle from: self fontName.
dirty := true.
@ -96,21 +110,11 @@ DiyaText >> fontStyle [
{ #category : #accessing }
DiyaText >> getCharsVerticesAt:i offset: offset on: tex2D [
|x y w h glyph gsize c texcoord|
c := (data at:i) asciiValue.
c = (Character space asciiValue) ifTrue:[
offset setX: (offset x + (tex2D spacing ) ) setY: offset y.
wrap ifTrue: [
(offset x + ((self nextSpaceFrom: i + 1) * (tex2D fontSize))) > (self extent x) ifTrue: [
offset setX: 0.0 setY: (offset y )- (tex2D linespace)].
].
^ {}.
].
c := (data at:i) asInteger.
glyph := tex2D getGlyph: c.
gsize := glyph extent.
((offset x > self extent x) and: (gsize x > 0)) ifTrue:[
wrap ifFalse: [ ^ { } ].
offset setX: 0.0 setY: (offset y )- (tex2D linespace).
offset y negated > self extent y ifTrue:[^{}].
].
x := offset x + (glyph bearing x).
y := offset y - (tex2D cellh).
@ -126,20 +130,35 @@ DiyaText >> getCharsVerticesAt:i offset: offset on: tex2D [
x + w. y + h. texcoord corner x. texcoord origin y. }.
]
{ #category : #accessing }
DiyaText >> getLinebreakIndices: delta [
|indices idx|
indices := Set new.
idx := delta + 1.
[
idx < data size
] whileTrue: [
indices add: (self lastSeparatorFrom: idx) + 1.
idx := idx + delta.
].
^indices
]
{ #category : #initialization }
DiyaText >> initialize [
super initialize.
self fontName: 'Ubuntu' style:'Regular' size: 16.
"self fontName: 'Ubuntu' style:'Regular' size: 16."
data := nil.
wrap := false.
bbox := nil.
texheight := 0.
self fontSize: 16
]
{ #category : #'as yet unclassified' }
DiyaText >> nextSpaceFrom: index [
index to: (data size) do: [:i|
(data at: i) = (Character space) ifTrue:[^i - index].
DiyaText >> lastSeparatorFrom: index [
index to: 1 by: -1 do: [:i|
(data at: i) isSeparator ifTrue:[^i].
].
^ 0
]

View File

@ -11,7 +11,8 @@ Class {
'rowp',
'face',
'maxbearing',
'maxrows'
'maxrows',
'meanww'
],
#pools : [
'OpenGLConstants',
@ -63,7 +64,7 @@ OpenGLFontTex >> fontSize [
{ #category : #'instance creation' }
OpenGLFontTex >> fromFace: aFace ofSize: size [
|minhang rec iptr charcode w|
|minhang rec iptr charcode w numw|
fontSize := size.
face := aFace.
charmap := Dictionary new.
@ -73,6 +74,8 @@ OpenGLFontTex >> fromFace: aFace ofSize: size [
iptr at:1 put: 0.
rec := (FTFaceRec fromHandle: face getHandle).
charcode := face getFirstChar: iptr getHandle.
meanww := 0.
numw := 0.
[ (iptr at: 1) = 0 ] whileFalse: [
face loadCharacter: charcode flags: (1 << 2).
w := ((rec glyph metrics width) >> 6).
@ -80,11 +83,14 @@ OpenGLFontTex >> fromFace: aFace ofSize: size [
maxbearing := maxbearing max: ((rec glyph metrics horiBearingY) >> 6).
cellw := cellw max: w.
minhang := minhang min: ((( rec glyph metrics horiBearingY) - (rec glyph metrics height)) >> 6).
meanww := meanww + w.
numw := numw + 1.
].
charcode := face getNextChar: charcode iptr: iptr getHandle.
].
cellh := maxbearing - minhang.
spacing := (cellw >> 2) asInteger.
meanww := meanww / numw.
maxrows := 8.
data := FFIExternalArray externalNewType: GLubyte size:cellw * cellh * (maxrows << 5).
LibC memset: data getHandle value: 0 size: data size.
@ -145,6 +151,11 @@ OpenGLFontTex >> linespace [
^ cellh
]
{ #category : #accessing }
OpenGLFontTex >> meanww [
^ meanww
]
{ #category : #accessing }
OpenGLFontTex >> reallocateBuffer [
|newbuffer|

View File

@ -1,9 +1,8 @@
Extension { #name : #'SDL_MouseMotionEvent' }
{ #category : #'*Diya' }
SDL_MouseMotionEvent >> triggableOn: aNode [
^false
"^ aNode inner: self worldPosition "
SDL_MouseMotionEvent >> triggableOn: arg1 [
^ arg1 inner: self worldPosition
]
{ #category : #'*Diya' }

View File

@ -7,5 +7,7 @@ SDL_TouchFingerEvent >> triggableOn: aNode [
{ #category : #'*Diya' }
SDL_TouchFingerEvent >> worldPosition [
^ (self x) @ (DiyaRendererContext uniqueInstance resolution y - self y )
|resolution|
resolution := DiyaRendererContext uniqueInstance resolution.
^((self x)* (resolution x) ) @ ((1.0 - self y)* (resolution y)).
]