Mercurial > repos > tabletprog
comparison samples/freetype.tp @ 326:50760ba52b11
Added basic rendering of strings to freetype demo
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 24 Mar 2015 21:50:28 -0700 |
parents | 615f23450f8f |
children | c1fad3d93861 |
comparison
equal
deleted
inserted
replaced
325:4a79311dbd29 | 326:50760ba52b11 |
---|---|
19 import: [ | 19 import: [ |
20 render | 20 render |
21 linearDesign | 21 linearDesign |
22 ] from: (freetype loadFlags) | 22 ] from: (freetype loadFlags) |
23 | 23 |
24 makeAtlas <- :renderer face size dpi color { | 24 makeAtlas <- :renderer face fontSize dpi color { |
25 face setCharSize: size res: dpi | 25 face setCharSize: fontSize res: dpi |
26 slot <- face glyphSlot | 26 slot <- face glyphSlot |
27 | 27 |
28 glyphs <- #[] | 28 glyphs <- #[] |
29 //TODO: Use a bytearray once that has an append method | 29 //TODO: Use a bytearray once that has an append method |
30 pixels <- #[] | 30 pixels <- #[] |
59 topOffset <- (slot bitmapTop) | 59 topOffset <- (slot bitmapTop) |
60 charCode <- char | 60 charCode <- char |
61 | 61 |
62 atlasX <- -1 | 62 atlasX <- -1 |
63 atlasY <- -1 | 63 atlasY <- -1 |
64 atlasRect <- { | |
65 sdl rect: atlasX atlasY size: width height | |
66 } | |
67 destRect <- :x y { | |
68 sdl rect: x + leftOffset y - topOffset size: width height | |
69 } | |
64 | 70 |
65 <= <- :other { | 71 <= <- :other { |
66 if: height > (other height) { | 72 if: height > (other height) { |
67 true | 73 true |
68 } else: { | 74 } else: { |
205 (val width) <= availPixels | 211 (val width) <= availPixels |
206 } | 212 } |
207 } | 213 } |
208 | 214 |
209 skinny value: :curGlyph { | 215 skinny value: :curGlyph { |
216 curGlyph atlasX!: curX | |
217 curGlyph atlasY!: curY | |
218 y <- 0 | |
219 dstY <- curY | |
220 idx <- curGlyph pixelOffset | |
221 while: { y < (curGlyph height) } do: { | |
222 dstIdx <- dstY * pitch + curX * 4 | |
223 x <- 0 | |
224 while: { x < (curGlyph width) } do: { | |
225 //FIXME: This will probably only work on little endian machines | |
226 bytearr set: dstIdx (pixels get: idx) | |
227 dstIdx <- dstIdx + 1 | |
228 bytearr set: dstIdx (color r) | |
229 dstIdx <- dstIdx + 1 | |
230 bytearr set: dstIdx (color g) | |
231 dstIdx <- dstIdx + 1 | |
232 bytearr set: dstIdx (color b) | |
233 dstIdx <- dstIdx + 1 | |
234 | |
235 idx <- idx + 1 | |
236 x <- x + 1 | |
237 } | |
238 y <- y + 1 | |
239 dstY <- dstY + 1 | |
240 } | |
241 | |
210 curX <- curX + (curGlyph width) | 242 curX <- curX + (curGlyph width) |
211 if: (curGlyph height) > minHeight { | 243 if: (curGlyph height) > minHeight { |
212 minHeight <- curGlyph height | 244 minHeight <- curGlyph height |
213 } | 245 } |
214 avail <- avail filter: :glyph { | 246 avail <- avail filter: :glyph { |
224 } | 256 } |
225 glyphDict <- dict hash | 257 glyphDict <- dict hash |
226 foreach: glyphs :idx glyph { | 258 foreach: glyphs :idx glyph { |
227 glyphDict set: (glyph charCode) glyph | 259 glyphDict set: (glyph charCode) glyph |
228 } | 260 } |
261 _pixelFactor <- ((face unitsPerEm) f64) * 72.0 / (fontSize * (dpi f64)) | |
229 option value: #{ | 262 option value: #{ |
230 texture <- drawTex | 263 texture <- drawTex |
231 width <- aWidth | 264 width <- aWidth |
232 height <- aHeight | 265 height <- aHeight |
233 glyphs <- glyphDict | 266 glyphs <- glyphDict |
267 drawString:at <- :str :x y { | |
268 //pixels to font units | |
269 designPosition <- (x f64) * _pixelFactor | |
270 charIdx <- 0 | |
271 | |
272 while: { charIdx < (str byte_length) } do: { | |
273 //TODO: UTF-8 | |
274 char <- (str byte: charIdx) uint32 | |
275 glyph <- glyphs get: char else: { | |
276 glyphs get: 0u32 else: { false } | |
277 } | |
278 texture copyRect: (glyph atlasRect) To: (glyph destRect: x y) | |
279 | |
280 designPosition <- designPosition + ((glyph hAdvance) f64) | |
281 x <- (designPosition / _pixelFactor + 0.5) truncInt32 | |
282 | |
283 charIdx <- charIdx + 1 | |
284 } | |
285 } | |
234 } | 286 } |
235 } none: { | 287 } none: { |
236 print: "Failed to create texture for atlas" | 288 print: "Failed to create texture for atlas" |
237 option none | 289 option none |
238 } | 290 } |
254 retcode <- 0 | 306 retcode <- 0 |
255 dpi <- 96 | 307 dpi <- 96 |
256 arg <- 1 | 308 arg <- 1 |
257 expectVal <- false | 309 expectVal <- false |
258 optName <- "" | 310 optName <- "" |
259 path <- "" | |
260 windowWidth <- 512 | 311 windowWidth <- 512 |
261 windowHeight <- 512 | 312 windowHeight <- 512 |
313 posArgs <- #[] | |
262 while: { arg < (args length) } do: { | 314 while: { arg < (args length) } do: { |
263 curArg <- args get: arg | 315 curArg <- args get: arg |
264 if: expectVal { | 316 if: expectVal { |
265 if: optName = "--dpi" || optName = "-d" { | 317 if: optName = "--dpi" || optName = "-d" { |
266 dpi <- curArg int32 | 318 dpi <- curArg int32 |
279 } else: { | 331 } else: { |
280 if: (curArg startsWith?: "-") { | 332 if: (curArg startsWith?: "-") { |
281 expectVal <- true | 333 expectVal <- true |
282 optName <- curArg | 334 optName <- curArg |
283 } else: { | 335 } else: { |
284 path <- curArg | 336 posArgs append: curArg |
285 } | 337 } |
286 } | 338 } |
287 arg <- arg + 1 | 339 arg <- arg + 1 |
288 } | 340 } |
341 path <- posArgs get: 0 | |
342 str <- if: (posArgs length) > 1 { posArgs get: 1 } else: { "" } | |
289 ft <- freetype init | 343 ft <- freetype init |
290 maybeFace <- ft faceFromPath: path index: 0 | 344 maybeFace <- ft faceFromPath: path index: 0 |
291 charCodes <- #[] | 345 charCodes <- #[] |
292 maybeFace value: :face { | 346 maybeFace value: :face { |
293 charMap <- face charmap | 347 charMap <- face charmap |
303 | 357 |
304 (makeAtlas: renderer face 12.0 dpi (sdl r: 0u8 g: 0u8 b: 0u8)) value: :atlas { | 358 (makeAtlas: renderer face 12.0 dpi (sdl r: 0u8 g: 0u8 b: 0u8)) value: :atlas { |
305 continue? <- true | 359 continue? <- true |
306 while: { continue? } do: { | 360 while: { continue? } do: { |
307 renderer clear | 361 renderer clear |
308 y <- 0 | 362 if: (str length) > 0 { |
309 x <- 0 | 363 atlas drawString: str at: 0 windowHeight / 2 |
310 while: { y < (atlas height) } do: { | 364 } else: { |
311 copyWidth <- if: (atlas width) < windowWidth { atlas width } else: { windowWidth } | 365 y <- 0 |
312 copyHeight <- if: (atlas height) < windowHeight { atlas height } else: { windowHeight } | 366 x <- 0 |
313 (atlas texture) copyRect: (sdl rect: 0 y size: copyWidth copyHeight) To: (sdl rect: x 0 size: copyWidth copyHeight) | 367 while: { y < (atlas height) } do: { |
314 y <- y + windowHeight | 368 copyWidth <- if: (atlas width) < windowWidth { atlas width } else: { windowWidth } |
315 x <- x + copyWidth | 369 copyHeight <- if: (atlas height) < windowHeight { atlas height } else: { windowHeight } |
370 (atlas texture) copyRect: (sdl rect: 0 y size: copyWidth copyHeight) To: (sdl rect: x 0 size: copyWidth copyHeight) | |
371 y <- y + windowHeight | |
372 x <- x + copyWidth | |
373 } | |
316 } | 374 } |
317 renderer present | 375 renderer present |
318 event <- option none | 376 event <- option none |
319 while: { | 377 while: { |
320 event <- sdl pollEvent | 378 event <- sdl pollEvent |