changeset 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 4a79311dbd29
children 860075fdc2d3
files modules/freetype.tp samples/freetype.tp
diffstat 2 files changed, 78 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/modules/freetype.tp	Tue Mar 24 21:49:45 2015 -0700
+++ b/modules/freetype.tp	Tue Mar 24 21:50:28 2015 -0700
@@ -224,6 +224,14 @@
 				ccall: makeSlot 1 opaque
 			}
 			
+			llMessage: unitsPerEm withVars: {
+				u16ret <- obj_uint16 ptr
+			} andCode: {
+				u16ret <- make_object: (addr_of: obj_uint16_meta) NULL 0
+				u16ret num!: (face units_per_EM)
+				u16ret
+			}
+			
 			firstChar <- {
 				_helper getFirstChar: faceOpaque _makeChar
 			}
--- a/samples/freetype.tp	Tue Mar 24 21:49:45 2015 -0700
+++ b/samples/freetype.tp	Tue Mar 24 21:50:28 2015 -0700
@@ -21,8 +21,8 @@
 		linearDesign
 	] from: (freetype loadFlags)
 	
-	makeAtlas <- :renderer face size dpi color {
-		face setCharSize: size res: dpi
+	makeAtlas <- :renderer face fontSize dpi color {
+		face setCharSize: fontSize res: dpi
 		slot <- face glyphSlot
 		
 		glyphs <- #[]
@@ -61,6 +61,12 @@
 				
 				atlasX <- -1
 				atlasY <- -1
+				atlasRect <- {
+					sdl rect: atlasX atlasY size: width height
+				}
+				destRect <- :x y {
+					sdl rect: x + leftOffset y - topOffset size: width height
+				}
 				
 				<= <- :other {
 					if: height > (other height) {
@@ -207,6 +213,32 @@
 							}
 							
 							skinny value: :curGlyph {
+								curGlyph atlasX!: curX
+								curGlyph atlasY!: curY
+								y <- 0
+								dstY <- curY
+								idx <- curGlyph pixelOffset
+								while: { y < (curGlyph height) } do: {
+									dstIdx <- dstY * pitch + curX * 4
+									x <- 0
+									while: { x < (curGlyph width) } do: {
+										//FIXME: This will probably only work on little endian machines
+										bytearr set: dstIdx (pixels get: idx)
+										dstIdx <- dstIdx + 1
+										bytearr set: dstIdx (color r)
+										dstIdx <- dstIdx + 1
+										bytearr set: dstIdx (color g)
+										dstIdx <- dstIdx + 1
+										bytearr set: dstIdx (color b)
+										dstIdx <- dstIdx + 1
+										
+										idx <- idx + 1
+										x <- x + 1
+									}
+									y <- y + 1
+									dstY <- dstY + 1
+								}
+							
 								curX <- curX + (curGlyph width)
 								if: (curGlyph height) > minHeight {
 									minHeight <- curGlyph height
@@ -226,11 +258,31 @@
 				foreach: glyphs :idx glyph {
 					glyphDict set: (glyph charCode) glyph
 				}
+				_pixelFactor <- ((face unitsPerEm) f64) * 72.0 / (fontSize * (dpi f64))
 				option value: #{
 					texture <- drawTex
 					width <- aWidth
 					height <- aHeight
 					glyphs <- glyphDict
+					drawString:at <- :str :x y {
+						//pixels to font units
+						designPosition <- (x f64) * _pixelFactor
+						charIdx <- 0
+						
+						while: { charIdx < (str byte_length) } do: {
+							//TODO: UTF-8
+							char <- (str byte: charIdx) uint32
+							glyph <- glyphs get: char else: {
+								glyphs get: 0u32 else: { false }
+							}
+							texture copyRect: (glyph atlasRect) To: (glyph destRect: x y)
+							
+							designPosition <- designPosition + ((glyph hAdvance) f64)
+							x <- (designPosition / _pixelFactor + 0.5) truncInt32
+							
+							charIdx <- charIdx + 1
+						}
+					}
 				}
 			} none: {
 				print: "Failed to create texture for atlas"
@@ -256,9 +308,9 @@
 		arg <- 1
 		expectVal <- false
 		optName <- ""
-		path <- ""
 		windowWidth <- 512
 		windowHeight <- 512
+		posArgs <- #[]
 		while: { arg < (args length) } do: {
 			curArg <- args get: arg
 			if: expectVal {
@@ -281,11 +333,13 @@
 					expectVal <- true
 					optName <- curArg
 				} else: {
-					path <- curArg
+					posArgs append: curArg
 				}
 			}
 			arg <- arg + 1
 		}
+		path <- posArgs get: 0
+		str <- if: (posArgs length) > 1 { posArgs get: 1 } else: { "" }
 		ft <- freetype init
 		maybeFace <- ft faceFromPath: path index: 0
 		charCodes <- #[]
@@ -305,14 +359,18 @@
 							continue? <- true
 							while: { continue? } do: {
 								renderer clear
-								y <- 0
-								x <- 0
-								while: { y < (atlas height) } do: {
-									copyWidth <- if: (atlas width) < windowWidth { atlas width } else: { windowWidth }
-									copyHeight <- if: (atlas height) < windowHeight { atlas height } else: { windowHeight }
-									(atlas texture) copyRect: (sdl rect: 0 y size: copyWidth copyHeight) To: (sdl rect: x 0 size: copyWidth copyHeight)
-									y <- y + windowHeight
-									x <- x + copyWidth
+								if: (str length) > 0 {
+									atlas drawString: str at: 0 windowHeight / 2
+								} else: {
+									y <- 0
+									x <- 0
+									while: { y < (atlas height) } do: {
+										copyWidth <- if: (atlas width) < windowWidth { atlas width } else: { windowWidth }
+										copyHeight <- if: (atlas height) < windowHeight { atlas height } else: { windowHeight }
+										(atlas texture) copyRect: (sdl rect: 0 y size: copyWidth copyHeight) To: (sdl rect: x 0 size: copyWidth copyHeight)
+										y <- y + windowHeight
+										x <- x + copyWidth
+									}
 								}
 								renderer present
 								event <- option none