]> gitweb.factorcode.org Git - factor.git/blobdiff - extra/tinyvg/tinyvg.factor
colors: using 255 * round >integer for hex conversion
[factor.git] / extra / tinyvg / tinyvg.factor
index 8af4969df6db11410c448a72f13c32f43aed0905..8500bd8830a6ca2d870c08a24ac593ae002c97c4 100644 (file)
@@ -1,9 +1,9 @@
 ! Copyright (C) 2021 John Benediktsson
 ! See http://factorcode.org/license.txt for BSD license
 
-USING: accessors colors combinators generalizations io io.binary
+USING: accessors colors combinators endian generalizations io
 io.encodings.binary io.files io.streams.byte-array kernel math
-math.bitwise namespaces sequences ;
+math.bitwise math.functions namespaces sequences ;
 
 IN: tinyvg
 
@@ -32,40 +32,13 @@ ERROR: invalid-length n ;
 : write-length ( n -- )
     dup 1 < [ invalid-length ] when 1 - write-varuint ;
 
-! Header
-
-CONSTANT: tinyvg-magic B{ 0x72 0x56 }
-
-CONSTANT: tinyvg-version 1
-
-TUPLE: tinyvg-header scale color-encoding coordinate-range width height color-count ;
-
-: read-tinyvg-header ( -- header )
-    2 read tinyvg-magic assert=
-    read1 tinyvg-version assert=
-    read1 [ 4 bits ] [ -4 shift 2 bits ] [ -6 shift ] tri
-    dup { 2 1 4 } nth '[ _ read le> ] 2 call-n
-    read-varuint tinyvg-header boa ;
-
-: write-tinyvg-header ( header -- )
-    tinyvg-magic write
-    tinyvg-version write1 {
-        [ scale>> ]
-        [ color-encoding>> 4 shift bitor ]
-        [ coordinate-range>> 6 shift bitor write1 ]
-        [ width>> ]
-        [ height>> ]
-        [ coordinate-range>> { 2 1 4 } nth '[ _ >le write ] bi@ ]
-        [ color-count>> write-varuint ]
-    } cleave ;
-
 ! Colors
 
 : read-rgba-8888 ( -- rgba )
     [ read1 255 /f ] 4 call-n <rgba> ;
 
 : write-rgba-8888 ( rgba -- )
-    >rgba-components [ 255 * >integer write1 ] 4 napply ;
+    >rgba-components [ 255 * round >integer write1 ] 4 napply ;
 
 : read-rgb-565 ( -- rgba )
     2 read le>
@@ -191,21 +164,22 @@ TUPLE: flat-colored color-index ;
 
 C: <flat-colored> flat-colored
 
-: read-flat-colored ( -- style )
-    read-color-index <flat-colored> ;
-
 TUPLE: gradient point0 point1 color-index0 color-index1 ;
 
 TUPLE: linear-gradient < gradient ;
 
+C: <linear-gradient> linear-gradient
+
 TUPLE: radial-gradient < gradient ;
 
+C: <radial-gradient> radial-gradient
+
 : read-gradient ( class -- style )
     [ [ read-point ] 2 call-n [ read-color-index ] 2 call-n ] dip boa ; inline
 
 : read-style ( style-kind -- style )
     {
-        { 0 [ read-flat-colored ] }
+        { 0 [ read-color-index <flat-colored> ] }
         { 1 [ linear-gradient read-gradient ] }
         { 2 [ radial-gradient read-gradient ] }
     } case ;
@@ -342,95 +316,53 @@ C: <outline-fill-path> outline-fill-path
 
 GENERIC: write-command ( command -- )
 
+:: write-fill ( command n seq -- )
+    command fill-style>> n write-style-kind
+    seq length write-length
+    command fill-style>> write-style ; inline
+
 M: fill-polygon write-command
-    {
-        [ fill-style>> 1 write-style-kind ]
-        [ polygon>> length write-length ]
-        [ fill-style>> write-style ]
-        [ polygon>> [ write-point ] each ]
-    } cleave ;
+    1 over polygon>> [ write-fill ] [ [ write-point ] each ] bi ;
 
 M: fill-rectangles write-command
-    {
-        [ fill-style>> 2 write-style-kind ]
-        [ rectangles>> length write-length ]
-        [ fill-style>> write-style ]
-        [ rectangles>> [ write-rectangle ] each ]
-    } cleave ;
+    2 over rectangles>> [ write-fill ] [ [ write-rectangle ] each ] bi ;
 
 M: fill-path write-command
-    {
-        [ fill-style>> 3 write-style-kind ]
-        [ path>> segments>> length write-length ]
-        [ fill-style>> write-style ]
-        [ path>> write-path ]
-    } cleave ;
+    3 over path>> [ write-fill ] [ write-path ] bi ;
+
+:: write-draw-line ( command n seq -- )
+    command line-style>> n write-style-kind
+    seq length write-length
+    command line-style>> write-style
+    command line-width>> write-unit ; inline
 
 M: draw-lines write-command
-    {
-        [ line-style>> 4 write-style-kind ]
-        [ lines>> length write-length ]
-        [ line-style>> write-style ]
-        [ line-width>> write-unit ]
-        [ lines>> [ write-line ] each ]
-    } cleave ;
+    4 over lines>> [ write-draw-line ] [ [ write-line ] each ] bi ;
 
 M: draw-line-loop write-command
-    {
-        [ line-style>> 5 write-style-kind ]
-        [ points>> length write-length ]
-        [ line-style>> write-style ]
-        [ line-width>> write-unit ]
-        [ points>> [ write-point ] each ]
-    } cleave ;
+    5 over points>> [ write-draw-line ] [ [ write-point ] each ] bi ;
 
 M: draw-line-strip write-command
-    {
-        [ line-style>> 6 write-style-kind ]
-        [ points>> length write-length ]
-        [ line-style>> write-style ]
-        [ line-width>> write-unit ]
-        [ points>> [ write-point ] each ]
-    } cleave ;
+    6 over points>> [ write-draw-line ] [ [ write-point ] each ] bi ;
 
 M: draw-line-path write-command
-    {
-        [ line-style>> 7 write-style-kind ]
-        [ path>> segments>> length write-length ]
-        [ line-style>> write-style ]
-        [ line-width>> write-unit ]
-        [ path>> write-path ]
-    } cleave ;
+    7 over path>> [ write-draw-line ] [ write-path ] bi ;
+
+:: write-outline-fill ( command n seq -- )
+    command fill-style>> n write-style-kind
+    command line-style>> seq length 1 - write-style-kind
+    command fill-style>> write-style
+    command line-style>> write-style
+    command line-width>> write-unit ; inline
 
 M: outline-fill-polygon write-command
-    {
-        [ fill-style>> 8 write-style-kind ]
-        [ [ line-style>> ] [ points>> length 1 - ] bi write-style-kind ]
-        [ fill-style>> write-style ]
-        [ line-style>> write-style ]
-        [ line-width>> write-unit ]
-        [ points>> [ write-point ] each ]
-    } cleave ;
+    8 over points>> [ write-outline-fill ] [ [ write-point ] each ] bi ;
 
 M: outline-fill-rectangles write-command
-    {
-        [ fill-style>> 9 write-style-kind ]
-        [ [ line-style>> ] [ rectangles>> length 1 - ] bi write-style-kind ]
-        [ fill-style>> write-style ]
-        [ line-style>> write-style ]
-        [ line-width>> write-unit ]
-        [ rectangles>> [ write-rectangle ] each ]
-    } cleave ;
+    9 over rectangles>> [ write-outline-fill ] [ [ write-rectangle ] each ] bi ;
 
 M: outline-fill-path write-command
-    {
-        [ fill-style>> 10 write-style-kind ]
-        [ [ line-style>> ] [ path>> segments>> length 1 - ] bi write-style-kind ]
-        [ fill-style>> write-style ]
-        [ line-style>> write-style ]
-        [ line-width>> write-unit ]
-        [ path>> write-path ]
-    } cleave ;
+    10 over path>> [ write-outline-fill ] [ write-path ] bi ;
 
 : write-commands ( commands -- )
     [ write-command ] each 0 write1 ;
@@ -474,7 +406,7 @@ TUPLE: quadratic-bezier < instruction control point1 ;
 C: <quadratic-bezier> quadratic-bezier
 
 : read-tag ( -- line-width/f tag )
-    read1 [ 4 bit? ] [ 3 bits ] bi [ [ read-unit ] [ f ] if ] dip ;
+    read1 [ 4 bit? [ read-unit ] [ f ] if ] [ 3 bits ] bi ;
 
 : read-arc ( -- large-arc? sweep? )
     read1 [ 0 bit? ] [ 1 bit? ] bi ;
@@ -554,43 +486,46 @@ C: <segment> segment
 : read-segment ( n -- segment )
     read-point swap read-instructions segment boa ;
 
-: read-segments ( n -- segments )
-    1 + [ read-varuint ] replicate [ read-segment ] map ;
-
 : write-segment ( segment -- )
     [ start>> write-point ] [ instructions>> [ write-instruction ] each ] bi ;
 
-: write-segments ( segments -- )
-    [ [ instructions>> length write-length ] each ]
-    [ [ write-segment ] each ] bi ;
-
 ! Path
 
-TUPLE: path segments ;
+: read-path ( segment-count -- segments )
+    1 + [ read-varuint ] replicate [ read-segment ] map ;
 
-C: <path> path
+: write-path ( segments -- )
+    [ [ instructions>> length write-length ] each ]
+    [ [ write-segment ] each ] bi ;
 
-: read-path ( segment-count -- path )
-    read-segments path boa ;
+! TinyVG
 
-: write-path ( path -- )
-    segments>> write-segments ;
+CONSTANT: tinyvg-magic B{ 0x72 0x56 }
 
-! TinyVG
+CONSTANT: tinyvg-version 1
 
-TUPLE: tinyvg header color-table commands ;
+TUPLE: tinyvg scale color-encoding coordinate-range width height color-table commands ;
 
 C: <tinyvg> tinyvg
 
 : read-tinyvg ( -- tinyvg )
     [
-        read-tinyvg-header
-        dup scale>> 2^ scale-factor set
-        dup color-encoding>> color-encoding set
-        dup coordinate-range>> coordinate-range set
-        dup color-count>> read-color-table dup color-table set
-        read-commands
-        <tinyvg>
+        tinyvg new
+            2 read tinyvg-magic assert=
+            read1 tinyvg-version assert=
+            read1 {
+                [ 4 bits >>scale ]
+                [ -4 shift 2 bits >>color-encoding ]
+                [ -6 shift [ >>coordinate-range ] keep ]
+            } cleave
+            { 2 1 4 } nth '[ _ read le> ] 2 call-n
+            [ >>width ] [ >>height ] bi*
+            dup scale>> 2^ scale-factor set
+            dup color-encoding>> color-encoding set
+            dup coordinate-range>> coordinate-range set
+            read-varuint read-color-table >>color-table
+            dup color-table>> color-table set
+            read-commands >>commands
     ] with-scope ;
 
 : path>tinyvg ( path -- tinyvg )
@@ -601,13 +536,20 @@ C: <tinyvg> tinyvg
 
 : write-tinyvg ( tinyvg -- )
     [
-        {
-            [ header>> write-tinyvg-header ]
-            [ header>> scale>> 2^ scale-factor set ]
-            [ header>> color-encoding>> color-encoding set ]
-            [ header>> coordinate-range>> coordinate-range set ]
-            [ color-table>> color-table set ]
+        tinyvg-magic write
+        tinyvg-version write1 {
+            [ scale>> ]
+            [ color-encoding>> 4 shift bitor ]
+            [ coordinate-range>> 6 shift bitor write1 ]
+            [ width>> ]
+            [ height>> ]
+            [ coordinate-range>> { 2 1 4 } nth '[ _ >le write ] bi@ ]
+            [ scale>> 2^ scale-factor set ]
+            [ color-encoding>> color-encoding set ]
+            [ coordinate-range>> coordinate-range set ]
+            [ color-table>> length write-varuint ]
             [ color-table>> [ write-color ] each ]
+            [ color-table>> color-table set ]
             [ commands>> write-commands ]
         } cleave
     ] with-scope ;