ftraster.c 103 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288
  1. /***************************************************************************/
  2. /* */
  3. /* ftraster.c */
  4. /* */
  5. /* The FreeType glyph rasterizer (body). */
  6. /* */
  7. /* Copyright 1996-2001, 2002 by */
  8. /* David Turner, Robert Wilhelm, and Werner Lemberg. */
  9. /* */
  10. /* This file is part of the FreeType project, and may only be used, */
  11. /* modified, and distributed under the terms of the FreeType project */
  12. /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
  13. /* this file you indicate that you have read the license and */
  14. /* understand and accept it fully. */
  15. /* */
  16. /***************************************************************************/
  17. /*************************************************************************/
  18. /* */
  19. /* This is a rewrite of the FreeType 1.x scan-line converter */
  20. /* */
  21. /*************************************************************************/
  22. #include <ft2build.h>
  23. #include "ftraster.h"
  24. #include FT_INTERNAL_CALC_H /* for FT_MulDiv only */
  25. /*************************************************************************/
  26. /* */
  27. /* A simple technical note on how the raster works */
  28. /* ----------------------------------------------- */
  29. /* */
  30. /* Converting an outline into a bitmap is achieved in several steps: */
  31. /* */
  32. /* 1 - Decomposing the outline into successive `profiles'. Each */
  33. /* profile is simply an array of scanline intersections on a given */
  34. /* dimension. A profile's main attributes are */
  35. /* */
  36. /* o its scanline position boundaries, i.e. `Ymin' and `Ymax'. */
  37. /* */
  38. /* o an array of intersection coordinates for each scanline */
  39. /* between `Ymin' and `Ymax'. */
  40. /* */
  41. /* o a direction, indicating whether it was built going `up' or */
  42. /* `down', as this is very important for filling rules. */
  43. /* */
  44. /* 2 - Sweeping the target map's scanlines in order to compute segment */
  45. /* `spans' which are then filled. Additionally, this pass */
  46. /* performs drop-out control. */
  47. /* */
  48. /* The outline data is parsed during step 1 only. The profiles are */
  49. /* built from the bottom of the render pool, used as a stack. The */
  50. /* following graphics shows the profile list under construction: */
  51. /* */
  52. /* ____________________________________________________________ _ _ */
  53. /* | | | | | */
  54. /* | profile | coordinates for | profile | coordinates for |--> */
  55. /* | 1 | profile 1 | 2 | profile 2 |--> */
  56. /* |_________|___________________|_________|_________________|__ _ _ */
  57. /* */
  58. /* ^ ^ */
  59. /* | | */
  60. /* start of render pool top */
  61. /* */
  62. /* The top of the profile stack is kept in the `top' variable. */
  63. /* */
  64. /* As you can see, a profile record is pushed on top of the render */
  65. /* pool, which is then followed by its coordinates/intersections. If */
  66. /* a change of direction is detected in the outline, a new profile is */
  67. /* generated until the end of the outline. */
  68. /* */
  69. /* Note that when all profiles have been generated, the function */
  70. /* Finalize_Profile_Table() is used to record, for each profile, its */
  71. /* bottom-most scanline as well as the scanline above its upmost */
  72. /* boundary. These positions are called `y-turns' because they (sort */
  73. /* of) correspond to local extrema. They are stored in a sorted list */
  74. /* built from the top of the render pool as a downwards stack: */
  75. /* */
  76. /* _ _ _______________________________________ */
  77. /* | | */
  78. /* <--| sorted list of | */
  79. /* <--| extrema scanlines | */
  80. /* _ _ __________________|____________________| */
  81. /* */
  82. /* ^ ^ */
  83. /* | | */
  84. /* maxBuff sizeBuff = end of pool */
  85. /* */
  86. /* This list is later used during the sweep phase in order to */
  87. /* optimize performance (see technical note on the sweep below). */
  88. /* */
  89. /* Of course, the raster detects whether the two stacks collide and */
  90. /* handles the situation propertly. */
  91. /* */
  92. /*************************************************************************/
  93. /*************************************************************************/
  94. /*************************************************************************/
  95. /** **/
  96. /** CONFIGURATION MACROS **/
  97. /** **/
  98. /*************************************************************************/
  99. /*************************************************************************/
  100. /* define DEBUG_RASTER if you want to compile a debugging version */
  101. #define xxxDEBUG_RASTER
  102. /* The default render pool size in bytes */
  103. #define RASTER_RENDER_POOL 8192
  104. /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */
  105. /* 5-levels anti-aliasing */
  106. #ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS
  107. #define FT_RASTER_OPTION_ANTI_ALIASING
  108. #endif
  109. /* The size of the two-lines intermediate bitmap used */
  110. /* for anti-aliasing, in bytes. */
  111. #define RASTER_GRAY_LINES 2048
  112. /*************************************************************************/
  113. /*************************************************************************/
  114. /** **/
  115. /** OTHER MACROS (do not change) **/
  116. /** **/
  117. /*************************************************************************/
  118. /*************************************************************************/
  119. /*************************************************************************/
  120. /* */
  121. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  122. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  123. /* messages during execution. */
  124. /* */
  125. #undef FT_COMPONENT
  126. #define FT_COMPONENT trace_raster
  127. #ifdef _STANDALONE_
  128. /* This macro is used to indicate that a function parameter is unused. */
  129. /* Its purpose is simply to reduce compiler warnings. Note also that */
  130. /* simply defining it as `(void)x' doesn't avoid warnings with certain */
  131. /* ANSI compilers (e.g. LCC). */
  132. #define FT_UNUSED( x ) (x) = (x)
  133. /* Disable the tracing mechanism for simplicity -- developers can */
  134. /* activate it easily by redefining these two macros. */
  135. #ifndef FT_ERROR
  136. #define FT_ERROR( x ) do ; while ( 0 ) /* nothing */
  137. #endif
  138. #ifndef FT_TRACE
  139. #define FT_TRACE( x ) do ; while ( 0 ) /* nothing */
  140. #endif
  141. #define Raster_Err_None 0
  142. #define Raster_Err_Not_Ini -1
  143. #define Raster_Err_Overflow -2
  144. #define Raster_Err_Neg_Height -3
  145. #define Raster_Err_Invalid -4
  146. #define Raster_Err_Unsupported -5
  147. #else /* _STANDALONE_ */
  148. #include FT_INTERNAL_OBJECTS_H
  149. #include FT_INTERNAL_DEBUG_H /* for FT_TRACE() and FT_ERROR() */
  150. #include "rasterrs.h"
  151. #define Raster_Err_None Raster_Err_Ok
  152. #define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized
  153. #define Raster_Err_Overflow Raster_Err_Raster_Overflow
  154. #define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height
  155. #define Raster_Err_Invalid Raster_Err_Invalid_Outline
  156. #define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph
  157. #endif /* _STANDALONE_ */
  158. #ifndef FT_MEM_SET
  159. #define FT_MEM_SET( d, s, c ) ft_memset( d, s, c )
  160. #endif
  161. /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */
  162. /* typically a small value and the result of a*b is known to fit into */
  163. /* 32 bits. */
  164. #define FMulDiv( a, b, c ) ( (a) * (b) / (c) )
  165. /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */
  166. /* for clipping computations. It simply uses the FT_MulDiv() function */
  167. /* defined in `ftcalc.h'. */
  168. #define SMulDiv FT_MulDiv
  169. /* The rasterizer is a very general purpose component; please leave */
  170. /* the following redefinitions there (you never know your target */
  171. /* environment). */
  172. #ifndef TRUE
  173. #define TRUE 1
  174. #endif
  175. #ifndef FALSE
  176. #define FALSE 0
  177. #endif
  178. #ifndef NULL
  179. #define NULL (void*)0
  180. #endif
  181. #ifndef SUCCESS
  182. #define SUCCESS 0
  183. #endif
  184. #ifndef FAILURE
  185. #define FAILURE 1
  186. #endif
  187. #define MaxBezier 32 /* The maximum number of stacked Bezier curves. */
  188. /* Setting this constant to more than 32 is a */
  189. /* pure waste of space. */
  190. #define Pixel_Bits 6 /* fractional bits of *input* coordinates */
  191. /*************************************************************************/
  192. /*************************************************************************/
  193. /** **/
  194. /** SIMPLE TYPE DECLARATIONS **/
  195. /** **/
  196. /*************************************************************************/
  197. /*************************************************************************/
  198. typedef int Int;
  199. typedef unsigned int UInt;
  200. typedef short Short;
  201. typedef unsigned short UShort, *PUShort;
  202. typedef long Long, *PLong;
  203. typedef unsigned long ULong;
  204. typedef unsigned char Byte, *PByte;
  205. typedef char Bool;
  206. typedef struct TPoint_
  207. {
  208. Long x;
  209. Long y;
  210. } TPoint;
  211. typedef enum TFlow_
  212. {
  213. Flow_None = 0,
  214. Flow_Up = 1,
  215. Flow_Down = -1
  216. } TFlow;
  217. /* States of each line, arc, and profile */
  218. typedef enum TStates_
  219. {
  220. Unknown_State,
  221. Ascending_State,
  222. Descending_State,
  223. Flat_State
  224. } TStates;
  225. typedef struct TProfile_ TProfile;
  226. typedef TProfile* PProfile;
  227. struct TProfile_
  228. {
  229. FT_F26Dot6 X; /* current coordinate during sweep */
  230. PProfile link; /* link to next profile - various purpose */
  231. PLong offset; /* start of profile's data in render pool */
  232. int flow; /* Profile orientation: Asc/Descending */
  233. long height; /* profile's height in scanlines */
  234. long start; /* profile's starting scanline */
  235. unsigned countL; /* number of lines to step before this */
  236. /* profile becomes drawable */
  237. PProfile next; /* next profile in same contour, used */
  238. /* during drop-out control */
  239. };
  240. typedef PProfile TProfileList;
  241. typedef PProfile* PProfileList;
  242. /* Simple record used to implement a stack of bands, required */
  243. /* by the sub-banding mechanism */
  244. typedef struct TBand_
  245. {
  246. Short y_min; /* band's minimum */
  247. Short y_max; /* band's maximum */
  248. } TBand;
  249. #define AlignProfileSize \
  250. ( ( sizeof ( TProfile ) + sizeof ( long ) - 1 ) / sizeof ( long ) )
  251. #ifdef TT_STATIC_RASTER
  252. #define RAS_ARGS /* void */
  253. #define RAS_ARG /* void */
  254. #define RAS_VARS /* void */
  255. #define RAS_VAR /* void */
  256. #define FT_UNUSED_RASTER do ; while ( 0 )
  257. #else /* TT_STATIC_RASTER */
  258. #define RAS_ARGS TRaster_Instance* raster,
  259. #define RAS_ARG TRaster_Instance* raster
  260. #define RAS_VARS raster,
  261. #define RAS_VAR raster
  262. #define FT_UNUSED_RASTER FT_UNUSED( raster )
  263. #endif /* TT_STATIC_RASTER */
  264. typedef struct TRaster_Instance_ TRaster_Instance;
  265. /* prototypes used for sweep function dispatch */
  266. typedef void
  267. Function_Sweep_Init( RAS_ARGS Short* min,
  268. Short* max );
  269. typedef void
  270. Function_Sweep_Span( RAS_ARGS Short y,
  271. FT_F26Dot6 x1,
  272. FT_F26Dot6 x2,
  273. PProfile left,
  274. PProfile right );
  275. typedef void
  276. Function_Sweep_Step( RAS_ARG );
  277. /* NOTE: These operations are only valid on 2's complement processors */
  278. #define FLOOR( x ) ( (x) & -ras.precision )
  279. #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision )
  280. #define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits )
  281. #define FRAC( x ) ( (x) & ( ras.precision - 1 ) )
  282. #define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half )
  283. /* Note that I have moved the location of some fields in the */
  284. /* structure to ensure that the most used variables are used */
  285. /* at the top. Thus, their offset can be coded with less */
  286. /* opcodes, and it results in a smaller executable. */
  287. struct TRaster_Instance_
  288. {
  289. Int precision_bits; /* precision related variables */
  290. Int precision;
  291. Int precision_half;
  292. Long precision_mask;
  293. Int precision_shift;
  294. Int precision_step;
  295. Int precision_jitter;
  296. Int scale_shift; /* == precision_shift for bitmaps */
  297. /* == precision_shift+1 for pixmaps */
  298. PLong buff; /* The profiles buffer */
  299. PLong sizeBuff; /* Render pool size */
  300. PLong maxBuff; /* Profiles buffer size */
  301. PLong top; /* Current cursor in buffer */
  302. FT_Error error;
  303. Int numTurns; /* number of Y-turns in outline */
  304. TPoint* arc; /* current Bezier arc pointer */
  305. UShort bWidth; /* target bitmap width */
  306. PByte bTarget; /* target bitmap buffer */
  307. PByte gTarget; /* target pixmap buffer */
  308. Long lastX, lastY, minY, maxY;
  309. UShort num_Profs; /* current number of profiles */
  310. Bool fresh; /* signals a fresh new profile which */
  311. /* 'start' field must be completed */
  312. Bool joint; /* signals that the last arc ended */
  313. /* exactly on a scanline. Allows */
  314. /* removal of doublets */
  315. PProfile cProfile; /* current profile */
  316. PProfile fProfile; /* head of linked list of profiles */
  317. PProfile gProfile; /* contour's first profile in case */
  318. /* of impact */
  319. TStates state; /* rendering state */
  320. FT_Bitmap target; /* description of target bit/pixmap */
  321. FT_Outline outline;
  322. Long traceOfs; /* current offset in target bitmap */
  323. Long traceG; /* current offset in target pixmap */
  324. Short traceIncr; /* sweep's increment in target bitmap */
  325. Short gray_min_x; /* current min x during gray rendering */
  326. Short gray_max_x; /* current max x during gray rendering */
  327. /* dispatch variables */
  328. Function_Sweep_Init* Proc_Sweep_Init;
  329. Function_Sweep_Span* Proc_Sweep_Span;
  330. Function_Sweep_Span* Proc_Sweep_Drop;
  331. Function_Sweep_Step* Proc_Sweep_Step;
  332. Byte dropOutControl; /* current drop_out control method */
  333. Bool second_pass; /* indicates wether a horizontal pass */
  334. /* should be performed to control */
  335. /* drop-out accurately when calling */
  336. /* Render_Glyph. Note that there is */
  337. /* no horizontal pass during gray */
  338. /* rendering. */
  339. TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */
  340. TBand band_stack[16]; /* band stack used for sub-banding */
  341. Int band_top; /* band stack top */
  342. Int count_table[256]; /* Look-up table used to quickly count */
  343. /* set bits in a gray 2x2 cell */
  344. void* memory;
  345. #ifdef FT_RASTER_OPTION_ANTI_ALIASING
  346. Byte grays[5]; /* Palette of gray levels used for */
  347. /* render. */
  348. Byte gray_lines[RASTER_GRAY_LINES];
  349. /* Intermediate table used to render the */
  350. /* graylevels pixmaps. */
  351. /* gray_lines is a buffer holding two */
  352. /* monochrome scanlines */
  353. Short gray_width; /* width in bytes of one monochrome */
  354. /* intermediate scanline of gray_lines. */
  355. /* Each gray pixel takes 2 bits long there */
  356. /* The gray_lines must hold 2 lines, thus with size */
  357. /* in bytes of at least `gray_width*2'. */
  358. #endif /* FT_RASTER_ANTI_ALIASING */
  359. #if 0
  360. PByte flags; /* current flags table */
  361. PUShort outs; /* current outlines table */
  362. FT_Vector* coords;
  363. UShort nPoints; /* number of points in current glyph */
  364. Short nContours; /* number of contours in current glyph */
  365. #endif
  366. };
  367. #ifdef FT_CONFIG_OPTION_STATIC_RASTER
  368. static TRaster_Instance cur_ras;
  369. #define ras cur_ras
  370. #else
  371. #define ras (*raster)
  372. #endif /* FT_CONFIG_OPTION_STATIC_RASTER */
  373. /*************************************************************************/
  374. /*************************************************************************/
  375. /** **/
  376. /** PROFILES COMPUTATION **/
  377. /** **/
  378. /*************************************************************************/
  379. /*************************************************************************/
  380. /*************************************************************************/
  381. /* */
  382. /* <Function> */
  383. /* Set_High_Precision */
  384. /* */
  385. /* <Description> */
  386. /* Sets precision variables according to param flag. */
  387. /* */
  388. /* <Input> */
  389. /* High :: Set to True for high precision (typically for ppem < 18), */
  390. /* false otherwise. */
  391. /* */
  392. static void
  393. Set_High_Precision( RAS_ARGS Int High )
  394. {
  395. if ( High )
  396. {
  397. ras.precision_bits = 10;
  398. ras.precision_step = 128;
  399. ras.precision_jitter = 24;
  400. }
  401. else
  402. {
  403. ras.precision_bits = 6;
  404. ras.precision_step = 32;
  405. ras.precision_jitter = 2;
  406. }
  407. FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" ));
  408. ras.precision = 1 << ras.precision_bits;
  409. ras.precision_half = ras.precision / 2;
  410. ras.precision_shift = ras.precision_bits - Pixel_Bits;
  411. ras.precision_mask = -ras.precision;
  412. }
  413. /*************************************************************************/
  414. /* */
  415. /* <Function> */
  416. /* New_Profile */
  417. /* */
  418. /* <Description> */
  419. /* Creates a new profile in the render pool. */
  420. /* */
  421. /* <Input> */
  422. /* aState :: The state/orientation of the new profile. */
  423. /* */
  424. /* <Return> */
  425. /* SUCCESS on success. FAILURE in case of overflow or of incoherent */
  426. /* profile. */
  427. /* */
  428. static Bool
  429. New_Profile( RAS_ARGS TStates aState )
  430. {
  431. if ( !ras.fProfile )
  432. {
  433. ras.cProfile = (PProfile)ras.top;
  434. ras.fProfile = ras.cProfile;
  435. ras.top += AlignProfileSize;
  436. }
  437. if ( ras.top >= ras.maxBuff )
  438. {
  439. ras.error = Raster_Err_Overflow;
  440. return FAILURE;
  441. }
  442. switch ( aState )
  443. {
  444. case Ascending_State:
  445. ras.cProfile->flow = Flow_Up;
  446. FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile ));
  447. break;
  448. case Descending_State:
  449. ras.cProfile->flow = Flow_Down;
  450. FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile ));
  451. break;
  452. default:
  453. FT_ERROR(( "New_Profile: invalid profile direction!\n" ));
  454. ras.error = Raster_Err_Invalid;
  455. return FAILURE;
  456. }
  457. ras.cProfile->start = 0;
  458. ras.cProfile->height = 0;
  459. ras.cProfile->offset = ras.top;
  460. ras.cProfile->link = (PProfile)0;
  461. ras.cProfile->next = (PProfile)0;
  462. if ( !ras.gProfile )
  463. ras.gProfile = ras.cProfile;
  464. ras.state = aState;
  465. ras.fresh = TRUE;
  466. ras.joint = FALSE;
  467. return SUCCESS;
  468. }
  469. /*************************************************************************/
  470. /* */
  471. /* <Function> */
  472. /* End_Profile */
  473. /* */
  474. /* <Description> */
  475. /* Finalizes the current profile. */
  476. /* */
  477. /* <Return> */
  478. /* SUCCESS on success. FAILURE in case of overflow or incoherency. */
  479. /* */
  480. static Bool
  481. End_Profile( RAS_ARG )
  482. {
  483. Long h;
  484. PProfile oldProfile;
  485. h = (Long)( ras.top - ras.cProfile->offset );
  486. if ( h < 0 )
  487. {
  488. FT_ERROR(( "End_Profile: negative height encountered!\n" ));
  489. ras.error = Raster_Err_Neg_Height;
  490. return FAILURE;
  491. }
  492. if ( h > 0 )
  493. {
  494. FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n",
  495. (long)ras.cProfile, ras.cProfile->start, h ));
  496. oldProfile = ras.cProfile;
  497. ras.cProfile->height = h;
  498. ras.cProfile = (PProfile)ras.top;
  499. ras.top += AlignProfileSize;
  500. ras.cProfile->height = 0;
  501. ras.cProfile->offset = ras.top;
  502. oldProfile->next = ras.cProfile;
  503. ras.num_Profs++;
  504. }
  505. if ( ras.top >= ras.maxBuff )
  506. {
  507. FT_TRACE1(( "overflow in End_Profile\n" ));
  508. ras.error = Raster_Err_Overflow;
  509. return FAILURE;
  510. }
  511. ras.joint = FALSE;
  512. return SUCCESS;
  513. }
  514. /*************************************************************************/
  515. /* */
  516. /* <Function> */
  517. /* Insert_Y_Turn */
  518. /* */
  519. /* <Description> */
  520. /* Inserts a salient into the sorted list placed on top of the render */
  521. /* pool. */
  522. /* */
  523. /* <Input> */
  524. /* New y scanline position. */
  525. /* */
  526. /* <Return> */
  527. /* SUCCESS on success. FAILURE in case of overflow. */
  528. /* */
  529. static Bool
  530. Insert_Y_Turn( RAS_ARGS Int y )
  531. {
  532. PLong y_turns;
  533. Int y2, n;
  534. n = ras.numTurns - 1;
  535. y_turns = ras.sizeBuff - ras.numTurns;
  536. /* look for first y value that is <= */
  537. while ( n >= 0 && y < y_turns[n] )
  538. n--;
  539. /* if it is <, simply insert it, ignore if == */
  540. if ( n >= 0 && y > y_turns[n] )
  541. while ( n >= 0 )
  542. {
  543. y2 = (Int)y_turns[n];
  544. y_turns[n] = y;
  545. y = y2;
  546. n--;
  547. }
  548. if ( n < 0 )
  549. {
  550. if ( ras.maxBuff <= ras.top )
  551. {
  552. ras.error = Raster_Err_Overflow;
  553. return FAILURE;
  554. }
  555. ras.maxBuff--;
  556. ras.numTurns++;
  557. ras.sizeBuff[-ras.numTurns] = y;
  558. }
  559. return SUCCESS;
  560. }
  561. /*************************************************************************/
  562. /* */
  563. /* <Function> */
  564. /* Finalize_Profile_Table */
  565. /* */
  566. /* <Description> */
  567. /* Adjusts all links in the profiles list. */
  568. /* */
  569. /* <Return> */
  570. /* SUCCESS on success. FAILURE in case of overflow. */
  571. /* */
  572. static Bool
  573. Finalize_Profile_Table( RAS_ARG )
  574. {
  575. Int bottom, top;
  576. UShort n;
  577. PProfile p;
  578. n = ras.num_Profs;
  579. if ( n > 1 )
  580. {
  581. p = ras.fProfile;
  582. while ( n > 0 )
  583. {
  584. if ( n > 1 )
  585. p->link = (PProfile)( p->offset + p->height );
  586. else
  587. p->link = NULL;
  588. switch ( p->flow )
  589. {
  590. case Flow_Down:
  591. bottom = (Int)( p->start - p->height + 1 );
  592. top = (Int)p->start;
  593. p->start = bottom;
  594. p->offset += p->height - 1;
  595. break;
  596. case Flow_Up:
  597. default:
  598. bottom = (Int)p->start;
  599. top = (Int)( p->start + p->height - 1 );
  600. }
  601. if ( Insert_Y_Turn( RAS_VARS bottom ) ||
  602. Insert_Y_Turn( RAS_VARS top + 1 ) )
  603. return FAILURE;
  604. p = p->link;
  605. n--;
  606. }
  607. }
  608. else
  609. ras.fProfile = NULL;
  610. return SUCCESS;
  611. }
  612. /*************************************************************************/
  613. /* */
  614. /* <Function> */
  615. /* Split_Conic */
  616. /* */
  617. /* <Description> */
  618. /* Subdivides one conic Bezier into two joint sub-arcs in the Bezier */
  619. /* stack. */
  620. /* */
  621. /* <Input> */
  622. /* None (subdivided Bezier is taken from the top of the stack). */
  623. /* */
  624. /* <Note> */
  625. /* This routine is the `beef' of this component. It is _the_ inner */
  626. /* loop that should be optimized to hell to get the best performance. */
  627. /* */
  628. static void
  629. Split_Conic( TPoint* base )
  630. {
  631. Long a, b;
  632. base[4].x = base[2].x;
  633. b = base[1].x;
  634. a = base[3].x = ( base[2].x + b ) / 2;
  635. b = base[1].x = ( base[0].x + b ) / 2;
  636. base[2].x = ( a + b ) / 2;
  637. base[4].y = base[2].y;
  638. b = base[1].y;
  639. a = base[3].y = ( base[2].y + b ) / 2;
  640. b = base[1].y = ( base[0].y + b ) / 2;
  641. base[2].y = ( a + b ) / 2;
  642. /* hand optimized. gcc doesn't seem to be too good at common */
  643. /* expression substitution and instruction scheduling ;-) */
  644. }
  645. /*************************************************************************/
  646. /* */
  647. /* <Function> */
  648. /* Split_Cubic */
  649. /* */
  650. /* <Description> */
  651. /* Subdivides a third-order Bezier arc into two joint sub-arcs in the */
  652. /* Bezier stack. */
  653. /* */
  654. /* <Note> */
  655. /* This routine is the `beef' of the component. It is one of _the_ */
  656. /* inner loops that should be optimized like hell to get the best */
  657. /* performance. */
  658. /* */
  659. static void
  660. Split_Cubic( TPoint* base )
  661. {
  662. Long a, b, c, d;
  663. base[6].x = base[3].x;
  664. c = base[1].x;
  665. d = base[2].x;
  666. base[1].x = a = ( base[0].x + c + 1 ) >> 1;
  667. base[5].x = b = ( base[3].x + d + 1 ) >> 1;
  668. c = ( c + d + 1 ) >> 1;
  669. base[2].x = a = ( a + c + 1 ) >> 1;
  670. base[4].x = b = ( b + c + 1 ) >> 1;
  671. base[3].x = ( a + b + 1 ) >> 1;
  672. base[6].y = base[3].y;
  673. c = base[1].y;
  674. d = base[2].y;
  675. base[1].y = a = ( base[0].y + c + 1 ) >> 1;
  676. base[5].y = b = ( base[3].y + d + 1 ) >> 1;
  677. c = ( c + d + 1 ) >> 1;
  678. base[2].y = a = ( a + c + 1 ) >> 1;
  679. base[4].y = b = ( b + c + 1 ) >> 1;
  680. base[3].y = ( a + b + 1 ) >> 1;
  681. }
  682. /*************************************************************************/
  683. /* */
  684. /* <Function> */
  685. /* Line_Up */
  686. /* */
  687. /* <Description> */
  688. /* Computes the x-coordinates of an ascending line segment and stores */
  689. /* them in the render pool. */
  690. /* */
  691. /* <Input> */
  692. /* x1 :: The x-coordinate of the segment's start point. */
  693. /* */
  694. /* y1 :: The y-coordinate of the segment's start point. */
  695. /* */
  696. /* x2 :: The x-coordinate of the segment's end point. */
  697. /* */
  698. /* y2 :: The y-coordinate of the segment's end point. */
  699. /* */
  700. /* miny :: A lower vertical clipping bound value. */
  701. /* */
  702. /* maxy :: An upper vertical clipping bound value. */
  703. /* */
  704. /* <Return> */
  705. /* SUCCESS on success, FAILURE on render pool overflow. */
  706. /* */
  707. static Bool
  708. Line_Up( RAS_ARGS Long x1,
  709. Long y1,
  710. Long x2,
  711. Long y2,
  712. Long miny,
  713. Long maxy )
  714. {
  715. Long Dx, Dy;
  716. Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */
  717. Long Ix, Rx, Ax;
  718. PLong top;
  719. Dx = x2 - x1;
  720. Dy = y2 - y1;
  721. if ( Dy <= 0 || y2 < miny || y1 > maxy )
  722. return SUCCESS;
  723. if ( y1 < miny )
  724. {
  725. /* Take care: miny-y1 can be a very large value; we use */
  726. /* a slow MulDiv function to avoid clipping bugs */
  727. x1 += SMulDiv( Dx, miny - y1, Dy );
  728. e1 = TRUNC( miny );
  729. f1 = 0;
  730. }
  731. else
  732. {
  733. e1 = (Int)TRUNC( y1 );
  734. f1 = (Int)FRAC( y1 );
  735. }
  736. if ( y2 > maxy )
  737. {
  738. /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */
  739. e2 = (Int)TRUNC( maxy );
  740. f2 = 0;
  741. }
  742. else
  743. {
  744. e2 = (Int)TRUNC( y2 );
  745. f2 = (Int)FRAC( y2 );
  746. }
  747. if ( f1 > 0 )
  748. {
  749. if ( e1 == e2 )
  750. return SUCCESS;
  751. else
  752. {
  753. x1 += FMulDiv( Dx, ras.precision - f1, Dy );
  754. e1 += 1;
  755. }
  756. }
  757. else
  758. if ( ras.joint )
  759. {
  760. ras.top--;
  761. ras.joint = FALSE;
  762. }
  763. ras.joint = (char)( f2 == 0 );
  764. if ( ras.fresh )
  765. {
  766. ras.cProfile->start = e1;
  767. ras.fresh = FALSE;
  768. }
  769. size = e2 - e1 + 1;
  770. if ( ras.top + size >= ras.maxBuff )
  771. {
  772. ras.error = Raster_Err_Overflow;
  773. return FAILURE;
  774. }
  775. if ( Dx > 0 )
  776. {
  777. Ix = ( ras.precision * Dx ) / Dy;
  778. Rx = ( ras.precision * Dx ) % Dy;
  779. Dx = 1;
  780. }
  781. else
  782. {
  783. Ix = -( ( ras.precision * -Dx ) / Dy );
  784. Rx = ( ras.precision * -Dx ) % Dy;
  785. Dx = -1;
  786. }
  787. Ax = -Dy;
  788. top = ras.top;
  789. while ( size > 0 )
  790. {
  791. *top++ = x1;
  792. x1 += Ix;
  793. Ax += Rx;
  794. if ( Ax >= 0 )
  795. {
  796. Ax -= Dy;
  797. x1 += Dx;
  798. }
  799. size--;
  800. }
  801. ras.top = top;
  802. return SUCCESS;
  803. }
  804. /*************************************************************************/
  805. /* */
  806. /* <Function> */
  807. /* Line_Down */
  808. /* */
  809. /* <Description> */
  810. /* Computes the x-coordinates of an descending line segment and */
  811. /* stores them in the render pool. */
  812. /* */
  813. /* <Input> */
  814. /* x1 :: The x-coordinate of the segment's start point. */
  815. /* */
  816. /* y1 :: The y-coordinate of the segment's start point. */
  817. /* */
  818. /* x2 :: The x-coordinate of the segment's end point. */
  819. /* */
  820. /* y2 :: The y-coordinate of the segment's end point. */
  821. /* */
  822. /* miny :: A lower vertical clipping bound value. */
  823. /* */
  824. /* maxy :: An upper vertical clipping bound value. */
  825. /* */
  826. /* <Return> */
  827. /* SUCCESS on success, FAILURE on render pool overflow. */
  828. /* */
  829. static Bool
  830. Line_Down( RAS_ARGS Long x1,
  831. Long y1,
  832. Long x2,
  833. Long y2,
  834. Long miny,
  835. Long maxy )
  836. {
  837. Bool result, fresh;
  838. fresh = ras.fresh;
  839. result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny );
  840. if ( fresh && !ras.fresh )
  841. ras.cProfile->start = -ras.cProfile->start;
  842. return result;
  843. }
  844. /* A function type describing the functions used to split Bezier arcs */
  845. typedef void (*TSplitter)( TPoint* base );
  846. /*************************************************************************/
  847. /* */
  848. /* <Function> */
  849. /* Bezier_Up */
  850. /* */
  851. /* <Description> */
  852. /* Computes the x-coordinates of an ascending Bezier arc and stores */
  853. /* them in the render pool. */
  854. /* */
  855. /* <Input> */
  856. /* degree :: The degree of the Bezier arc (either 2 or 3). */
  857. /* */
  858. /* splitter :: The function to split Bezier arcs. */
  859. /* */
  860. /* miny :: A lower vertical clipping bound value. */
  861. /* */
  862. /* maxy :: An upper vertical clipping bound value. */
  863. /* */
  864. /* <Return> */
  865. /* SUCCESS on success, FAILURE on render pool overflow. */
  866. /* */
  867. static Bool
  868. Bezier_Up( RAS_ARGS Int degree,
  869. TSplitter splitter,
  870. Long miny,
  871. Long maxy )
  872. {
  873. Long y1, y2, e, e2, e0;
  874. Short f1;
  875. TPoint* arc;
  876. TPoint* start_arc;
  877. PLong top;
  878. arc = ras.arc;
  879. y1 = arc[degree].y;
  880. y2 = arc[0].y;
  881. top = ras.top;
  882. if ( y2 < miny || y1 > maxy )
  883. goto Fin;
  884. e2 = FLOOR( y2 );
  885. if ( e2 > maxy )
  886. e2 = maxy;
  887. e0 = miny;
  888. if ( y1 < miny )
  889. e = miny;
  890. else
  891. {
  892. e = CEILING( y1 );
  893. f1 = (Short)( FRAC( y1 ) );
  894. e0 = e;
  895. if ( f1 == 0 )
  896. {
  897. if ( ras.joint )
  898. {
  899. top--;
  900. ras.joint = FALSE;
  901. }
  902. *top++ = arc[degree].x;
  903. e += ras.precision;
  904. }
  905. }
  906. if ( ras.fresh )
  907. {
  908. ras.cProfile->start = TRUNC( e0 );
  909. ras.fresh = FALSE;
  910. }
  911. if ( e2 < e )
  912. goto Fin;
  913. if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
  914. {
  915. ras.top = top;
  916. ras.error = Raster_Err_Overflow;
  917. return FAILURE;
  918. }
  919. start_arc = arc;
  920. while ( arc >= start_arc && e <= e2 )
  921. {
  922. ras.joint = FALSE;
  923. y2 = arc[0].y;
  924. if ( y2 > e )
  925. {
  926. y1 = arc[degree].y;
  927. if ( y2 - y1 >= ras.precision_step )
  928. {
  929. splitter( arc );
  930. arc += degree;
  931. }
  932. else
  933. {
  934. *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x,
  935. e - y1, y2 - y1 );
  936. arc -= degree;
  937. e += ras.precision;
  938. }
  939. }
  940. else
  941. {
  942. if ( y2 == e )
  943. {
  944. ras.joint = TRUE;
  945. *top++ = arc[0].x;
  946. e += ras.precision;
  947. }
  948. arc -= degree;
  949. }
  950. }
  951. Fin:
  952. ras.top = top;
  953. ras.arc -= degree;
  954. return SUCCESS;
  955. }
  956. /*************************************************************************/
  957. /* */
  958. /* <Function> */
  959. /* Bezier_Down */
  960. /* */
  961. /* <Description> */
  962. /* Computes the x-coordinates of an descending Bezier arc and stores */
  963. /* them in the render pool. */
  964. /* */
  965. /* <Input> */
  966. /* degree :: The degree of the Bezier arc (either 2 or 3). */
  967. /* */
  968. /* splitter :: The function to split Bezier arcs. */
  969. /* */
  970. /* miny :: A lower vertical clipping bound value. */
  971. /* */
  972. /* maxy :: An upper vertical clipping bound value. */
  973. /* */
  974. /* <Return> */
  975. /* SUCCESS on success, FAILURE on render pool overflow. */
  976. /* */
  977. static Bool
  978. Bezier_Down( RAS_ARGS Int degree,
  979. TSplitter splitter,
  980. Long miny,
  981. Long maxy )
  982. {
  983. TPoint* arc = ras.arc;
  984. Bool result, fresh;
  985. arc[0].y = -arc[0].y;
  986. arc[1].y = -arc[1].y;
  987. arc[2].y = -arc[2].y;
  988. if ( degree > 2 )
  989. arc[3].y = -arc[3].y;
  990. fresh = ras.fresh;
  991. result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny );
  992. if ( fresh && !ras.fresh )
  993. ras.cProfile->start = -ras.cProfile->start;
  994. arc[0].y = -arc[0].y;
  995. return result;
  996. }
  997. /*************************************************************************/
  998. /* */
  999. /* <Function> */
  1000. /* Line_To */
  1001. /* */
  1002. /* <Description> */
  1003. /* Injects a new line segment and adjusts Profiles list. */
  1004. /* */
  1005. /* <Input> */
  1006. /* x :: The x-coordinate of the segment's end point (its start point */
  1007. /* is stored in `LastX'). */
  1008. /* */
  1009. /* y :: The y-coordinate of the segment's end point (its start point */
  1010. /* is stored in `LastY'). */
  1011. /* */
  1012. /* <Return> */
  1013. /* SUCCESS on success, FAILURE on render pool overflow or incorrect */
  1014. /* profile. */
  1015. /* */
  1016. static Bool
  1017. Line_To( RAS_ARGS Long x,
  1018. Long y )
  1019. {
  1020. /* First, detect a change of direction */
  1021. switch ( ras.state )
  1022. {
  1023. case Unknown_State:
  1024. if ( y > ras.lastY )
  1025. {
  1026. if ( New_Profile( RAS_VARS Ascending_State ) )
  1027. return FAILURE;
  1028. }
  1029. else
  1030. {
  1031. if ( y < ras.lastY )
  1032. if ( New_Profile( RAS_VARS Descending_State ) )
  1033. return FAILURE;
  1034. }
  1035. break;
  1036. case Ascending_State:
  1037. if ( y < ras.lastY )
  1038. {
  1039. if ( End_Profile( RAS_VAR ) ||
  1040. New_Profile( RAS_VARS Descending_State ) )
  1041. return FAILURE;
  1042. }
  1043. break;
  1044. case Descending_State:
  1045. if ( y > ras.lastY )
  1046. {
  1047. if ( End_Profile( RAS_VAR ) ||
  1048. New_Profile( RAS_VARS Ascending_State ) )
  1049. return FAILURE;
  1050. }
  1051. break;
  1052. default:
  1053. ;
  1054. }
  1055. /* Then compute the lines */
  1056. switch ( ras.state )
  1057. {
  1058. case Ascending_State:
  1059. if ( Line_Up( RAS_VARS ras.lastX, ras.lastY,
  1060. x, y, ras.minY, ras.maxY ) )
  1061. return FAILURE;
  1062. break;
  1063. case Descending_State:
  1064. if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,
  1065. x, y, ras.minY, ras.maxY ) )
  1066. return FAILURE;
  1067. break;
  1068. default:
  1069. ;
  1070. }
  1071. ras.lastX = x;
  1072. ras.lastY = y;
  1073. return SUCCESS;
  1074. }
  1075. /*************************************************************************/
  1076. /* */
  1077. /* <Function> */
  1078. /* Conic_To */
  1079. /* */
  1080. /* <Description> */
  1081. /* Injects a new conic arc and adjusts the profile list. */
  1082. /* */
  1083. /* <Input> */
  1084. /* cx :: The x-coordinate of the arc's new control point. */
  1085. /* */
  1086. /* cy :: The y-coordinate of the arc's new control point. */
  1087. /* */
  1088. /* x :: The x-coordinate of the arc's end point (its start point is */
  1089. /* stored in `LastX'). */
  1090. /* */
  1091. /* y :: The y-coordinate of the arc's end point (its start point is */
  1092. /* stored in `LastY'). */
  1093. /* */
  1094. /* <Return> */
  1095. /* SUCCESS on success, FAILURE on render pool overflow or incorrect */
  1096. /* profile. */
  1097. /* */
  1098. static Bool
  1099. Conic_To( RAS_ARGS Long cx,
  1100. Long cy,
  1101. Long x,
  1102. Long y )
  1103. {
  1104. Long y1, y2, y3, x3, ymin, ymax;
  1105. TStates state_bez;
  1106. ras.arc = ras.arcs;
  1107. ras.arc[2].x = ras.lastX;
  1108. ras.arc[2].y = ras.lastY;
  1109. ras.arc[1].x = cx; ras.arc[1].y = cy;
  1110. ras.arc[0].x = x; ras.arc[0].y = y;
  1111. do
  1112. {
  1113. y1 = ras.arc[2].y;
  1114. y2 = ras.arc[1].y;
  1115. y3 = ras.arc[0].y;
  1116. x3 = ras.arc[0].x;
  1117. /* first, categorize the Bezier arc */
  1118. if ( y1 <= y3 )
  1119. {
  1120. ymin = y1;
  1121. ymax = y3;
  1122. }
  1123. else
  1124. {
  1125. ymin = y3;
  1126. ymax = y1;
  1127. }
  1128. if ( y2 < ymin || y2 > ymax )
  1129. {
  1130. /* this arc has no given direction, split it! */
  1131. Split_Conic( ras.arc );
  1132. ras.arc += 2;
  1133. }
  1134. else if ( y1 == y3 )
  1135. {
  1136. /* this arc is flat, ignore it and pop it from the Bezier stack */
  1137. ras.arc -= 2;
  1138. }
  1139. else
  1140. {
  1141. /* the arc is y-monotonous, either ascending or descending */
  1142. /* detect a change of direction */
  1143. state_bez = y1 < y3 ? Ascending_State : Descending_State;
  1144. if ( ras.state != state_bez )
  1145. {
  1146. /* finalize current profile if any */
  1147. if ( ras.state != Unknown_State &&
  1148. End_Profile( RAS_VAR ) )
  1149. goto Fail;
  1150. /* create a new profile */
  1151. if ( New_Profile( RAS_VARS state_bez ) )
  1152. goto Fail;
  1153. }
  1154. /* now call the appropriate routine */
  1155. if ( state_bez == Ascending_State )
  1156. {
  1157. if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
  1158. goto Fail;
  1159. }
  1160. else
  1161. if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
  1162. goto Fail;
  1163. }
  1164. } while ( ras.arc >= ras.arcs );
  1165. ras.lastX = x3;
  1166. ras.lastY = y3;
  1167. return SUCCESS;
  1168. Fail:
  1169. return FAILURE;
  1170. }
  1171. /*************************************************************************/
  1172. /* */
  1173. /* <Function> */
  1174. /* Cubic_To */
  1175. /* */
  1176. /* <Description> */
  1177. /* Injects a new cubic arc and adjusts the profile list. */
  1178. /* */
  1179. /* <Input> */
  1180. /* cx1 :: The x-coordinate of the arc's first new control point. */
  1181. /* */
  1182. /* cy1 :: The y-coordinate of the arc's first new control point. */
  1183. /* */
  1184. /* cx2 :: The x-coordinate of the arc's second new control point. */
  1185. /* */
  1186. /* cy2 :: The y-coordinate of the arc's second new control point. */
  1187. /* */
  1188. /* x :: The x-coordinate of the arc's end point (its start point is */
  1189. /* stored in `LastX'). */
  1190. /* */
  1191. /* y :: The y-coordinate of the arc's end point (its start point is */
  1192. /* stored in `LastY'). */
  1193. /* */
  1194. /* <Return> */
  1195. /* SUCCESS on success, FAILURE on render pool overflow or incorrect */
  1196. /* profile. */
  1197. /* */
  1198. static Bool
  1199. Cubic_To( RAS_ARGS Long cx1,
  1200. Long cy1,
  1201. Long cx2,
  1202. Long cy2,
  1203. Long x,
  1204. Long y )
  1205. {
  1206. Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
  1207. TStates state_bez;
  1208. ras.arc = ras.arcs;
  1209. ras.arc[3].x = ras.lastX;
  1210. ras.arc[3].y = ras.lastY;
  1211. ras.arc[2].x = cx1; ras.arc[2].y = cy1;
  1212. ras.arc[1].x = cx2; ras.arc[1].y = cy2;
  1213. ras.arc[0].x = x; ras.arc[0].y = y;
  1214. do
  1215. {
  1216. y1 = ras.arc[3].y;
  1217. y2 = ras.arc[2].y;
  1218. y3 = ras.arc[1].y;
  1219. y4 = ras.arc[0].y;
  1220. x4 = ras.arc[0].x;
  1221. /* first, categorize the Bezier arc */
  1222. if ( y1 <= y4 )
  1223. {
  1224. ymin1 = y1;
  1225. ymax1 = y4;
  1226. }
  1227. else
  1228. {
  1229. ymin1 = y4;
  1230. ymax1 = y1;
  1231. }
  1232. if ( y2 <= y3 )
  1233. {
  1234. ymin2 = y2;
  1235. ymax2 = y3;
  1236. }
  1237. else
  1238. {
  1239. ymin2 = y3;
  1240. ymax2 = y2;
  1241. }
  1242. if ( ymin2 < ymin1 || ymax2 > ymax1 )
  1243. {
  1244. /* this arc has no given direction, split it! */
  1245. Split_Cubic( ras.arc );
  1246. ras.arc += 3;
  1247. }
  1248. else if ( y1 == y4 )
  1249. {
  1250. /* this arc is flat, ignore it and pop it from the Bezier stack */
  1251. ras.arc -= 3;
  1252. }
  1253. else
  1254. {
  1255. state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State;
  1256. /* detect a change of direction */
  1257. if ( ras.state != state_bez )
  1258. {
  1259. if ( ras.state != Unknown_State &&
  1260. End_Profile( RAS_VAR ) )
  1261. goto Fail;
  1262. if ( New_Profile( RAS_VARS state_bez ) )
  1263. goto Fail;
  1264. }
  1265. /* compute intersections */
  1266. if ( state_bez == Ascending_State )
  1267. {
  1268. if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
  1269. goto Fail;
  1270. }
  1271. else
  1272. if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
  1273. goto Fail;
  1274. }
  1275. } while ( ras.arc >= ras.arcs );
  1276. ras.lastX = x4;
  1277. ras.lastY = y4;
  1278. return SUCCESS;
  1279. Fail:
  1280. return FAILURE;
  1281. }
  1282. #undef SWAP_
  1283. #define SWAP_( x, y ) do \
  1284. { \
  1285. Long swap = x; \
  1286. \
  1287. \
  1288. x = y; \
  1289. y = swap; \
  1290. } while ( 0 )
  1291. /*************************************************************************/
  1292. /* */
  1293. /* <Function> */
  1294. /* Decompose_Curve */
  1295. /* */
  1296. /* <Description> */
  1297. /* Scans the outline arays in order to emit individual segments and */
  1298. /* Beziers by calling Line_To() and Bezier_To(). It handles all */
  1299. /* weird cases, like when the first point is off the curve, or when */
  1300. /* there are simply no `on' points in the contour! */
  1301. /* */
  1302. /* <Input> */
  1303. /* first :: The index of the first point in the contour. */
  1304. /* */
  1305. /* last :: The index of the last point in the contour. */
  1306. /* */
  1307. /* flipped :: If set, flip the direction of the curve. */
  1308. /* */
  1309. /* <Return> */
  1310. /* SUCCESS on success, FAILURE on error. */
  1311. /* */
  1312. static Bool
  1313. Decompose_Curve( RAS_ARGS UShort first,
  1314. UShort last,
  1315. int flipped )
  1316. {
  1317. FT_Vector v_last;
  1318. FT_Vector v_control;
  1319. FT_Vector v_start;
  1320. FT_Vector* points;
  1321. FT_Vector* point;
  1322. FT_Vector* limit;
  1323. char* tags;
  1324. unsigned tag; /* current point's state */
  1325. points = ras.outline.points;
  1326. limit = points + last;
  1327. v_start.x = SCALED( points[first].x );
  1328. v_start.y = SCALED( points[first].y );
  1329. v_last.x = SCALED( points[last].x );
  1330. v_last.y = SCALED( points[last].y );
  1331. if ( flipped )
  1332. {
  1333. SWAP_( v_start.x, v_start.y );
  1334. SWAP_( v_last.x, v_last.y );
  1335. }
  1336. v_control = v_start;
  1337. point = points + first;
  1338. tags = ras.outline.tags + first;
  1339. tag = FT_CURVE_TAG( tags[0] );
  1340. /* A contour cannot start with a cubic control point! */
  1341. if ( tag == FT_CURVE_TAG_CUBIC )
  1342. goto Invalid_Outline;
  1343. /* check first point to determine origin */
  1344. if ( tag == FT_CURVE_TAG_CONIC )
  1345. {
  1346. /* first point is conic control. Yes, this happens. */
  1347. if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON )
  1348. {
  1349. /* start at last point if it is on the curve */
  1350. v_start = v_last;
  1351. limit--;
  1352. }
  1353. else
  1354. {
  1355. /* if both first and last points are conic, */
  1356. /* start at their middle and record its position */
  1357. /* for closure */
  1358. v_start.x = ( v_start.x + v_last.x ) / 2;
  1359. v_start.y = ( v_start.y + v_last.y ) / 2;
  1360. v_last = v_start;
  1361. }
  1362. point--;
  1363. tags--;
  1364. }
  1365. ras.lastX = v_start.x;
  1366. ras.lastY = v_start.y;
  1367. while ( point < limit )
  1368. {
  1369. point++;
  1370. tags++;
  1371. tag = FT_CURVE_TAG( tags[0] );
  1372. switch ( tag )
  1373. {
  1374. case FT_CURVE_TAG_ON: /* emit a single line_to */
  1375. {
  1376. Long x, y;
  1377. x = SCALED( point->x );
  1378. y = SCALED( point->y );
  1379. if ( flipped )
  1380. SWAP_( x, y );
  1381. if ( Line_To( RAS_VARS x, y ) )
  1382. goto Fail;
  1383. continue;
  1384. }
  1385. case FT_CURVE_TAG_CONIC: /* consume conic arcs */
  1386. v_control.x = SCALED( point[0].x );
  1387. v_control.y = SCALED( point[0].y );
  1388. if ( flipped )
  1389. SWAP_( v_control.x, v_control.y );
  1390. Do_Conic:
  1391. if ( point < limit )
  1392. {
  1393. FT_Vector v_middle;
  1394. Long x, y;
  1395. point++;
  1396. tags++;
  1397. tag = FT_CURVE_TAG( tags[0] );
  1398. x = SCALED( point[0].x );
  1399. y = SCALED( point[0].y );
  1400. if ( flipped )
  1401. SWAP_( x, y );
  1402. if ( tag == FT_CURVE_TAG_ON )
  1403. {
  1404. if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) )
  1405. goto Fail;
  1406. continue;
  1407. }
  1408. if ( tag != FT_CURVE_TAG_CONIC )
  1409. goto Invalid_Outline;
  1410. v_middle.x = ( v_control.x + x ) / 2;
  1411. v_middle.y = ( v_control.y + y ) / 2;
  1412. if ( Conic_To( RAS_VARS v_control.x, v_control.y,
  1413. v_middle.x, v_middle.y ) )
  1414. goto Fail;
  1415. v_control.x = x;
  1416. v_control.y = y;
  1417. goto Do_Conic;
  1418. }
  1419. if ( Conic_To( RAS_VARS v_control.x, v_control.y,
  1420. v_start.x, v_start.y ) )
  1421. goto Fail;
  1422. goto Close;
  1423. default: /* FT_CURVE_TAG_CUBIC */
  1424. {
  1425. Long x1, y1, x2, y2, x3, y3;
  1426. if ( point + 1 > limit ||
  1427. FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
  1428. goto Invalid_Outline;
  1429. point += 2;
  1430. tags += 2;
  1431. x1 = SCALED( point[-2].x );
  1432. y1 = SCALED( point[-2].y );
  1433. x2 = SCALED( point[-1].x );
  1434. y2 = SCALED( point[-1].y );
  1435. x3 = SCALED( point[ 0].x );
  1436. y3 = SCALED( point[ 0].y );
  1437. if ( flipped )
  1438. {
  1439. SWAP_( x1, y1 );
  1440. SWAP_( x2, y2 );
  1441. SWAP_( x3, y3 );
  1442. }
  1443. if ( point <= limit )
  1444. {
  1445. if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) )
  1446. goto Fail;
  1447. continue;
  1448. }
  1449. if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) )
  1450. goto Fail;
  1451. goto Close;
  1452. }
  1453. }
  1454. }
  1455. /* close the contour with a line segment */
  1456. if ( Line_To( RAS_VARS v_start.x, v_start.y ) )
  1457. goto Fail;
  1458. Close:
  1459. return SUCCESS;
  1460. Invalid_Outline:
  1461. ras.error = Raster_Err_Invalid;
  1462. Fail:
  1463. return FAILURE;
  1464. }
  1465. /*************************************************************************/
  1466. /* */
  1467. /* <Function> */
  1468. /* Convert_Glyph */
  1469. /* */
  1470. /* <Description> */
  1471. /* Converts a glyph into a series of segments and arcs and makes a */
  1472. /* profiles list with them. */
  1473. /* */
  1474. /* <Input> */
  1475. /* flipped :: If set, flip the direction of curve. */
  1476. /* */
  1477. /* <Return> */
  1478. /* SUCCESS on success, FAILURE if any error was encountered during */
  1479. /* rendering. */
  1480. /* */
  1481. static Bool
  1482. Convert_Glyph( RAS_ARGS int flipped )
  1483. {
  1484. int i;
  1485. unsigned start;
  1486. PProfile lastProfile;
  1487. ras.fProfile = NULL;
  1488. ras.joint = FALSE;
  1489. ras.fresh = FALSE;
  1490. ras.maxBuff = ras.sizeBuff - AlignProfileSize;
  1491. ras.numTurns = 0;
  1492. ras.cProfile = (PProfile)ras.top;
  1493. ras.cProfile->offset = ras.top;
  1494. ras.num_Profs = 0;
  1495. start = 0;
  1496. for ( i = 0; i < ras.outline.n_contours; i++ )
  1497. {
  1498. ras.state = Unknown_State;
  1499. ras.gProfile = NULL;
  1500. if ( Decompose_Curve( RAS_VARS (unsigned short)start,
  1501. ras.outline.contours[i],
  1502. flipped ) )
  1503. return FAILURE;
  1504. start = ras.outline.contours[i] + 1;
  1505. /* We must now see whether the extreme arcs join or not */
  1506. if ( FRAC( ras.lastY ) == 0 &&
  1507. ras.lastY >= ras.minY &&
  1508. ras.lastY <= ras.maxY )
  1509. if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow )
  1510. ras.top--;
  1511. /* Note that ras.gProfile can be nil if the contour was too small */
  1512. /* to be drawn. */
  1513. lastProfile = ras.cProfile;
  1514. if ( End_Profile( RAS_VAR ) )
  1515. return FAILURE;
  1516. /* close the `next profile in contour' linked list */
  1517. if ( ras.gProfile )
  1518. lastProfile->next = ras.gProfile;
  1519. }
  1520. if ( Finalize_Profile_Table( RAS_VAR ) )
  1521. return FAILURE;
  1522. return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE );
  1523. }
  1524. /*************************************************************************/
  1525. /*************************************************************************/
  1526. /** **/
  1527. /** SCAN-LINE SWEEPS AND DRAWING **/
  1528. /** **/
  1529. /*************************************************************************/
  1530. /*************************************************************************/
  1531. /*************************************************************************/
  1532. /* */
  1533. /* Init_Linked */
  1534. /* */
  1535. /* Initializes an empty linked list. */
  1536. /* */
  1537. static void
  1538. Init_Linked( TProfileList* l )
  1539. {
  1540. *l = NULL;
  1541. }
  1542. /*************************************************************************/
  1543. /* */
  1544. /* InsNew */
  1545. /* */
  1546. /* Inserts a new profile in a linked list. */
  1547. /* */
  1548. static void
  1549. InsNew( PProfileList list,
  1550. PProfile profile )
  1551. {
  1552. PProfile *old, current;
  1553. Long x;
  1554. old = list;
  1555. current = *old;
  1556. x = profile->X;
  1557. while ( current )
  1558. {
  1559. if ( x < current->X )
  1560. break;
  1561. old = &current->link;
  1562. current = *old;
  1563. }
  1564. profile->link = current;
  1565. *old = profile;
  1566. }
  1567. /*************************************************************************/
  1568. /* */
  1569. /* DelOld */
  1570. /* */
  1571. /* Removes an old profile from a linked list. */
  1572. /* */
  1573. static void
  1574. DelOld( PProfileList list,
  1575. PProfile profile )
  1576. {
  1577. PProfile *old, current;
  1578. old = list;
  1579. current = *old;
  1580. while ( current )
  1581. {
  1582. if ( current == profile )
  1583. {
  1584. *old = current->link;
  1585. return;
  1586. }
  1587. old = &current->link;
  1588. current = *old;
  1589. }
  1590. /* we should never get there, unless the profile was not part of */
  1591. /* the list. */
  1592. }
  1593. /*************************************************************************/
  1594. /* */
  1595. /* Sort */
  1596. /* */
  1597. /* Sorts a trace list. In 95%, the list is already sorted. We need */
  1598. /* an algorithm which is fast in this case. Bubble sort is enough */
  1599. /* and simple. */
  1600. /* */
  1601. static void
  1602. Sort( PProfileList list )
  1603. {
  1604. PProfile *old, current, next;
  1605. /* First, set the new X coordinate of each profile */
  1606. current = *list;
  1607. while ( current )
  1608. {
  1609. current->X = *current->offset;
  1610. current->offset += current->flow;
  1611. current->height--;
  1612. current = current->link;
  1613. }
  1614. /* Then sort them */
  1615. old = list;
  1616. current = *old;
  1617. if ( !current )
  1618. return;
  1619. next = current->link;
  1620. while ( next )
  1621. {
  1622. if ( current->X <= next->X )
  1623. {
  1624. old = &current->link;
  1625. current = *old;
  1626. if ( !current )
  1627. return;
  1628. }
  1629. else
  1630. {
  1631. *old = next;
  1632. current->link = next->link;
  1633. next->link = current;
  1634. old = list;
  1635. current = *old;
  1636. }
  1637. next = current->link;
  1638. }
  1639. }
  1640. /*************************************************************************/
  1641. /* */
  1642. /* Vertical Sweep Procedure Set */
  1643. /* */
  1644. /* These four routines are used during the vertical black/white sweep */
  1645. /* phase by the generic Draw_Sweep() function. */
  1646. /* */
  1647. /*************************************************************************/
  1648. static void
  1649. Vertical_Sweep_Init( RAS_ARGS Short* min,
  1650. Short* max )
  1651. {
  1652. Long pitch = ras.target.pitch;
  1653. FT_UNUSED( max );
  1654. ras.traceIncr = (Short)-pitch;
  1655. ras.traceOfs = -*min * pitch;
  1656. if ( pitch > 0 )
  1657. ras.traceOfs += ( ras.target.rows - 1 ) * pitch;
  1658. ras.gray_min_x = 0;
  1659. ras.gray_max_x = 0;
  1660. }
  1661. static void
  1662. Vertical_Sweep_Span( RAS_ARGS Short y,
  1663. FT_F26Dot6 x1,
  1664. FT_F26Dot6 x2,
  1665. PProfile left,
  1666. PProfile right )
  1667. {
  1668. Long e1, e2;
  1669. int c1, c2;
  1670. Byte f1, f2;
  1671. Byte* target;
  1672. FT_UNUSED( y );
  1673. FT_UNUSED( left );
  1674. FT_UNUSED( right );
  1675. /* Drop-out control */
  1676. e1 = TRUNC( CEILING( x1 ) );
  1677. if ( x2 - x1 - ras.precision <= ras.precision_jitter )
  1678. e2 = e1;
  1679. else
  1680. e2 = TRUNC( FLOOR( x2 ) );
  1681. if ( e2 >= 0 && e1 < ras.bWidth )
  1682. {
  1683. if ( e1 < 0 )
  1684. e1 = 0;
  1685. if ( e2 >= ras.bWidth )
  1686. e2 = ras.bWidth - 1;
  1687. c1 = (Short)( e1 >> 3 );
  1688. c2 = (Short)( e2 >> 3 );
  1689. f1 = (Byte) ( 0xFF >> ( e1 & 7 ) );
  1690. f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );
  1691. if ( ras.gray_min_x > c1 ) ras.gray_min_x = (short)c1;
  1692. if ( ras.gray_max_x < c2 ) ras.gray_max_x = (short)c2;
  1693. target = ras.bTarget + ras.traceOfs + c1;
  1694. c2 -= c1;
  1695. if ( c2 > 0 )
  1696. {
  1697. target[0] |= f1;
  1698. /* memset() is slower than the following code on many platforms. */
  1699. /* This is due to the fact that, in the vast majority of cases, */
  1700. /* the span length in bytes is relatively small. */
  1701. c2--;
  1702. while ( c2 > 0 )
  1703. {
  1704. *(++target) = 0xFF;
  1705. c2--;
  1706. }
  1707. target[1] |= f2;
  1708. }
  1709. else
  1710. *target |= ( f1 & f2 );
  1711. }
  1712. }
  1713. static void
  1714. Vertical_Sweep_Drop( RAS_ARGS Short y,
  1715. FT_F26Dot6 x1,
  1716. FT_F26Dot6 x2,
  1717. PProfile left,
  1718. PProfile right )
  1719. {
  1720. Long e1, e2;
  1721. Short c1, f1;
  1722. /* Drop-out control */
  1723. e1 = CEILING( x1 );
  1724. e2 = FLOOR ( x2 );
  1725. if ( e1 > e2 )
  1726. {
  1727. if ( e1 == e2 + ras.precision )
  1728. {
  1729. switch ( ras.dropOutControl )
  1730. {
  1731. case 1:
  1732. e1 = e2;
  1733. break;
  1734. case 4:
  1735. e1 = CEILING( (x1 + x2 + 1) / 2 );
  1736. break;
  1737. case 2:
  1738. case 5:
  1739. /* Drop-out Control Rule #4 */
  1740. /* The spec is not very clear regarding rule #4. It */
  1741. /* presents a method that is way too costly to implement */
  1742. /* while the general idea seems to get rid of `stubs'. */
  1743. /* */
  1744. /* Here, we only get rid of stubs recognized if: */
  1745. /* */
  1746. /* upper stub: */
  1747. /* */
  1748. /* - P_Left and P_Right are in the same contour */
  1749. /* - P_Right is the successor of P_Left in that contour */
  1750. /* - y is the top of P_Left and P_Right */
  1751. /* */
  1752. /* lower stub: */
  1753. /* */
  1754. /* - P_Left and P_Right are in the same contour */
  1755. /* - P_Left is the successor of P_Right in that contour */
  1756. /* - y is the bottom of P_Left */
  1757. /* */
  1758. /* FIXXXME: uncommenting this line solves the disappearing */
  1759. /* bit problem in the `7' of verdana 10pts, but */
  1760. /* makes a new one in the `C' of arial 14pts */
  1761. #if 0
  1762. if ( x2 - x1 < ras.precision_half )
  1763. #endif
  1764. {
  1765. /* upper stub test */
  1766. if ( left->next == right && left->height <= 0 )
  1767. return;
  1768. /* lower stub test */
  1769. if ( right->next == left && left->start == y )
  1770. return;
  1771. }
  1772. /* check that the rightmost pixel isn't set */
  1773. e1 = TRUNC( e1 );
  1774. c1 = (Short)( e1 >> 3 );
  1775. f1 = (Short)( e1 & 7 );
  1776. if ( e1 >= 0 && e1 < ras.bWidth &&
  1777. ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
  1778. return;
  1779. if ( ras.dropOutControl == 2 )
  1780. e1 = e2;
  1781. else
  1782. e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
  1783. break;
  1784. default:
  1785. return; /* unsupported mode */
  1786. }
  1787. }
  1788. else
  1789. return;
  1790. }
  1791. e1 = TRUNC( e1 );
  1792. if ( e1 >= 0 && e1 < ras.bWidth )
  1793. {
  1794. c1 = (Short)( e1 >> 3 );
  1795. f1 = (Short)( e1 & 7 );
  1796. if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
  1797. if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1;
  1798. ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
  1799. }
  1800. }
  1801. static void
  1802. Vertical_Sweep_Step( RAS_ARG )
  1803. {
  1804. ras.traceOfs += ras.traceIncr;
  1805. }
  1806. /***********************************************************************/
  1807. /* */
  1808. /* Horizontal Sweep Procedure Set */
  1809. /* */
  1810. /* These four routines are used during the horizontal black/white */
  1811. /* sweep phase by the generic Draw_Sweep() function. */
  1812. /* */
  1813. /***********************************************************************/
  1814. static void
  1815. Horizontal_Sweep_Init( RAS_ARGS Short* min,
  1816. Short* max )
  1817. {
  1818. /* nothing, really */
  1819. FT_UNUSED( raster );
  1820. FT_UNUSED( min );
  1821. FT_UNUSED( max );
  1822. }
  1823. static void
  1824. Horizontal_Sweep_Span( RAS_ARGS Short y,
  1825. FT_F26Dot6 x1,
  1826. FT_F26Dot6 x2,
  1827. PProfile left,
  1828. PProfile right )
  1829. {
  1830. Long e1, e2;
  1831. PByte bits;
  1832. Byte f1;
  1833. FT_UNUSED( left );
  1834. FT_UNUSED( right );
  1835. if ( x2 - x1 < ras.precision )
  1836. {
  1837. e1 = CEILING( x1 );
  1838. e2 = FLOOR ( x2 );
  1839. if ( e1 == e2 )
  1840. {
  1841. bits = ras.bTarget + ( y >> 3 );
  1842. f1 = (Byte)( 0x80 >> ( y & 7 ) );
  1843. e1 = TRUNC( e1 );
  1844. if ( e1 >= 0 && e1 < ras.target.rows )
  1845. {
  1846. PByte p;
  1847. p = bits - e1*ras.target.pitch;
  1848. if ( ras.target.pitch > 0 )
  1849. p += ( ras.target.rows - 1 ) * ras.target.pitch;
  1850. p[0] |= f1;
  1851. }
  1852. }
  1853. }
  1854. }
  1855. static void
  1856. Horizontal_Sweep_Drop( RAS_ARGS Short y,
  1857. FT_F26Dot6 x1,
  1858. FT_F26Dot6 x2,
  1859. PProfile left,
  1860. PProfile right )
  1861. {
  1862. Long e1, e2;
  1863. PByte bits;
  1864. Byte f1;
  1865. /* During the horizontal sweep, we only take care of drop-outs */
  1866. e1 = CEILING( x1 );
  1867. e2 = FLOOR ( x2 );
  1868. if ( e1 > e2 )
  1869. {
  1870. if ( e1 == e2 + ras.precision )
  1871. {
  1872. switch ( ras.dropOutControl )
  1873. {
  1874. case 1:
  1875. e1 = e2;
  1876. break;
  1877. case 4:
  1878. e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
  1879. break;
  1880. case 2:
  1881. case 5:
  1882. /* Drop-out Control Rule #4 */
  1883. /* The spec is not very clear regarding rule #4. It */
  1884. /* presents a method that is way too costly to implement */
  1885. /* while the general idea seems to get rid of `stubs'. */
  1886. /* */
  1887. /* rightmost stub test */
  1888. if ( left->next == right && left->height <= 0 )
  1889. return;
  1890. /* leftmost stub test */
  1891. if ( right->next == left && left->start == y )
  1892. return;
  1893. /* check that the rightmost pixel isn't set */
  1894. e1 = TRUNC( e1 );
  1895. bits = ras.bTarget + ( y >> 3 );
  1896. f1 = (Byte)( 0x80 >> ( y & 7 ) );
  1897. bits -= e1 * ras.target.pitch;
  1898. if ( ras.target.pitch > 0 )
  1899. bits += ( ras.target.rows - 1 ) * ras.target.pitch;
  1900. if ( e1 >= 0 &&
  1901. e1 < ras.target.rows &&
  1902. *bits & f1 )
  1903. return;
  1904. if ( ras.dropOutControl == 2 )
  1905. e1 = e2;
  1906. else
  1907. e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
  1908. break;
  1909. default:
  1910. return; /* unsupported mode */
  1911. }
  1912. }
  1913. else
  1914. return;
  1915. }
  1916. bits = ras.bTarget + ( y >> 3 );
  1917. f1 = (Byte)( 0x80 >> ( y & 7 ) );
  1918. e1 = TRUNC( e1 );
  1919. if ( e1 >= 0 && e1 < ras.target.rows )
  1920. {
  1921. bits -= e1 * ras.target.pitch;
  1922. if ( ras.target.pitch > 0 )
  1923. bits += ( ras.target.rows - 1 ) * ras.target.pitch;
  1924. bits[0] |= f1;
  1925. }
  1926. }
  1927. static void
  1928. Horizontal_Sweep_Step( RAS_ARG )
  1929. {
  1930. /* Nothing, really */
  1931. FT_UNUSED( raster );
  1932. }
  1933. #ifdef FT_RASTER_OPTION_ANTI_ALIASING
  1934. /*************************************************************************/
  1935. /* */
  1936. /* Vertical Gray Sweep Procedure Set */
  1937. /* */
  1938. /* These two routines are used during the vertical gray-levels sweep */
  1939. /* phase by the generic Draw_Sweep() function. */
  1940. /* */
  1941. /* NOTES */
  1942. /* */
  1943. /* - The target pixmap's width *must* be a multiple of 4. */
  1944. /* */
  1945. /* - You have to use the function Vertical_Sweep_Span() for the gray */
  1946. /* span call. */
  1947. /* */
  1948. /*************************************************************************/
  1949. static void
  1950. Vertical_Gray_Sweep_Init( RAS_ARGS Short* min,
  1951. Short* max )
  1952. {
  1953. Long pitch, byte_len;
  1954. *min = *min & -2;
  1955. *max = ( *max + 3 ) & -2;
  1956. ras.traceOfs = 0;
  1957. pitch = ras.target.pitch;
  1958. byte_len = -pitch;
  1959. ras.traceIncr = (Short)byte_len;
  1960. ras.traceG = ( *min / 2 ) * byte_len;
  1961. if ( pitch > 0 )
  1962. {
  1963. ras.traceG += ( ras.target.rows - 1 ) * pitch;
  1964. byte_len = -byte_len;
  1965. }
  1966. ras.gray_min_x = (Short)byte_len;
  1967. ras.gray_max_x = -(Short)byte_len;
  1968. }
  1969. static void
  1970. Vertical_Gray_Sweep_Step( RAS_ARG )
  1971. {
  1972. Int c1, c2;
  1973. PByte pix, bit, bit2;
  1974. Int* count = ras.count_table;
  1975. Byte* grays;
  1976. ras.traceOfs += ras.gray_width;
  1977. if ( ras.traceOfs > ras.gray_width )
  1978. {
  1979. pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
  1980. grays = ras.grays;
  1981. if ( ras.gray_max_x >= 0 )
  1982. {
  1983. Long last_pixel = ras.target.width - 1;
  1984. Int last_cell = last_pixel >> 2;
  1985. Int last_bit = last_pixel & 3;
  1986. Bool over = 0;
  1987. if ( ras.gray_max_x >= last_cell && last_bit != 3 )
  1988. {
  1989. ras.gray_max_x = last_cell - 1;
  1990. over = 1;
  1991. }
  1992. if ( ras.gray_min_x < 0 )
  1993. ras.gray_min_x = 0;
  1994. bit = ras.bTarget + ras.gray_min_x;
  1995. bit2 = bit + ras.gray_width;
  1996. c1 = ras.gray_max_x - ras.gray_min_x;
  1997. while ( c1 >= 0 )
  1998. {
  1999. c2 = count[*bit] + count[*bit2];
  2000. if ( c2 )
  2001. {
  2002. pix[0] = grays[(c2 >> 12) & 0x000F];
  2003. pix[1] = grays[(c2 >> 8 ) & 0x000F];
  2004. pix[2] = grays[(c2 >> 4 ) & 0x000F];
  2005. pix[3] = grays[ c2 & 0x000F];
  2006. *bit = 0;
  2007. *bit2 = 0;
  2008. }
  2009. bit++;
  2010. bit2++;
  2011. pix += 4;
  2012. c1--;
  2013. }
  2014. if ( over )
  2015. {
  2016. c2 = count[*bit] + count[*bit2];
  2017. if ( c2 )
  2018. {
  2019. switch ( last_bit )
  2020. {
  2021. case 2:
  2022. pix[2] = grays[(c2 >> 4 ) & 0x000F];
  2023. case 1:
  2024. pix[1] = grays[(c2 >> 8 ) & 0x000F];
  2025. default:
  2026. pix[0] = grays[(c2 >> 12) & 0x000F];
  2027. }
  2028. *bit = 0;
  2029. *bit2 = 0;
  2030. }
  2031. }
  2032. }
  2033. ras.traceOfs = 0;
  2034. ras.traceG += ras.traceIncr;
  2035. ras.gray_min_x = 32000;
  2036. ras.gray_max_x = -32000;
  2037. }
  2038. }
  2039. static void
  2040. Horizontal_Gray_Sweep_Span( RAS_ARGS Short y,
  2041. FT_F26Dot6 x1,
  2042. FT_F26Dot6 x2,
  2043. PProfile left,
  2044. PProfile right )
  2045. {
  2046. /* nothing, really */
  2047. FT_UNUSED( raster );
  2048. FT_UNUSED( y );
  2049. FT_UNUSED( x1 );
  2050. FT_UNUSED( x2 );
  2051. FT_UNUSED( left );
  2052. FT_UNUSED( right );
  2053. }
  2054. static void
  2055. Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y,
  2056. FT_F26Dot6 x1,
  2057. FT_F26Dot6 x2,
  2058. PProfile left,
  2059. PProfile right )
  2060. {
  2061. Long e1, e2;
  2062. PByte pixel;
  2063. Byte color;
  2064. /* During the horizontal sweep, we only take care of drop-outs */
  2065. e1 = CEILING( x1 );
  2066. e2 = FLOOR ( x2 );
  2067. if ( e1 > e2 )
  2068. {
  2069. if ( e1 == e2 + ras.precision )
  2070. {
  2071. switch ( ras.dropOutControl )
  2072. {
  2073. case 1:
  2074. e1 = e2;
  2075. break;
  2076. case 4:
  2077. e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
  2078. break;
  2079. case 2:
  2080. case 5:
  2081. /* Drop-out Control Rule #4 */
  2082. /* The spec is not very clear regarding rule #4. It */
  2083. /* presents a method that is way too costly to implement */
  2084. /* while the general idea seems to get rid of `stubs'. */
  2085. /* */
  2086. /* rightmost stub test */
  2087. if ( left->next == right && left->height <= 0 )
  2088. return;
  2089. /* leftmost stub test */
  2090. if ( right->next == left && left->start == y )
  2091. return;
  2092. if ( ras.dropOutControl == 2 )
  2093. e1 = e2;
  2094. else
  2095. e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
  2096. break;
  2097. default:
  2098. return; /* unsupported mode */
  2099. }
  2100. }
  2101. else
  2102. return;
  2103. }
  2104. if ( e1 >= 0 )
  2105. {
  2106. if ( x2 - x1 >= ras.precision_half )
  2107. color = ras.grays[2];
  2108. else
  2109. color = ras.grays[1];
  2110. e1 = TRUNC( e1 ) / 2;
  2111. if ( e1 < ras.target.rows )
  2112. {
  2113. pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;
  2114. if ( ras.target.pitch > 0 )
  2115. pixel += ( ras.target.rows - 1 ) * ras.target.pitch;
  2116. if ( pixel[0] == ras.grays[0] )
  2117. pixel[0] = color;
  2118. }
  2119. }
  2120. }
  2121. #endif /* FT_RASTER_OPTION_ANTI_ALIASING */
  2122. /*************************************************************************/
  2123. /* */
  2124. /* Generic Sweep Drawing routine */
  2125. /* */
  2126. /*************************************************************************/
  2127. static Bool
  2128. Draw_Sweep( RAS_ARG )
  2129. {
  2130. Short y, y_change, y_height;
  2131. PProfile P, Q, P_Left, P_Right;
  2132. Short min_Y, max_Y, top, bottom, dropouts;
  2133. Long x1, x2, xs, e1, e2;
  2134. TProfileList waiting;
  2135. TProfileList draw_left, draw_right;
  2136. /* Init empty linked lists */
  2137. Init_Linked( &waiting );
  2138. Init_Linked( &draw_left );
  2139. Init_Linked( &draw_right );
  2140. /* first, compute min and max Y */
  2141. P = ras.fProfile;
  2142. max_Y = (Short)TRUNC( ras.minY );
  2143. min_Y = (Short)TRUNC( ras.maxY );
  2144. while ( P )
  2145. {
  2146. Q = P->link;
  2147. bottom = (Short)P->start;
  2148. top = (Short)( P->start + P->height - 1 );
  2149. if ( min_Y > bottom ) min_Y = bottom;
  2150. if ( max_Y < top ) max_Y = top;
  2151. P->X = 0;
  2152. InsNew( &waiting, P );
  2153. P = Q;
  2154. }
  2155. /* Check the Y-turns */
  2156. if ( ras.numTurns == 0 )
  2157. {
  2158. ras.error = Raster_Err_Invalid;
  2159. return FAILURE;
  2160. }
  2161. /* Now inits the sweep */
  2162. ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y );
  2163. /* Then compute the distance of each profile from min_Y */
  2164. P = waiting;
  2165. while ( P )
  2166. {
  2167. P->countL = (UShort)( P->start - min_Y );
  2168. P = P->link;
  2169. }
  2170. /* Let's go */
  2171. y = min_Y;
  2172. y_height = 0;
  2173. if ( ras.numTurns > 0 &&
  2174. ras.sizeBuff[-ras.numTurns] == min_Y )
  2175. ras.numTurns--;
  2176. while ( ras.numTurns > 0 )
  2177. {
  2178. /* look in the waiting list for new activations */
  2179. P = waiting;
  2180. while ( P )
  2181. {
  2182. Q = P->link;
  2183. P->countL -= y_height;
  2184. if ( P->countL == 0 )
  2185. {
  2186. DelOld( &waiting, P );
  2187. switch ( P->flow )
  2188. {
  2189. case Flow_Up:
  2190. InsNew( &draw_left, P );
  2191. break;
  2192. case Flow_Down:
  2193. InsNew( &draw_right, P );
  2194. break;
  2195. }
  2196. }
  2197. P = Q;
  2198. }
  2199. /* Sort the drawing lists */
  2200. Sort( &draw_left );
  2201. Sort( &draw_right );
  2202. y_change = (Short)ras.sizeBuff[-ras.numTurns--];
  2203. y_height = (Short)( y_change - y );
  2204. while ( y < y_change )
  2205. {
  2206. /* Let's trace */
  2207. dropouts = 0;
  2208. P_Left = draw_left;
  2209. P_Right = draw_right;
  2210. while ( P_Left )
  2211. {
  2212. x1 = P_Left ->X;
  2213. x2 = P_Right->X;
  2214. if ( x1 > x2 )
  2215. {
  2216. xs = x1;
  2217. x1 = x2;
  2218. x2 = xs;
  2219. }
  2220. if ( x2 - x1 <= ras.precision )
  2221. {
  2222. e1 = FLOOR( x1 );
  2223. e2 = CEILING( x2 );
  2224. if ( ras.dropOutControl != 0 &&
  2225. ( e1 > e2 || e2 == e1 + ras.precision ) )
  2226. {
  2227. /* a drop out was detected */
  2228. P_Left ->X = x1;
  2229. P_Right->X = x2;
  2230. /* mark profile for drop-out processing */
  2231. P_Left->countL = 1;
  2232. dropouts++;
  2233. goto Skip_To_Next;
  2234. }
  2235. }
  2236. ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right );
  2237. Skip_To_Next:
  2238. P_Left = P_Left->link;
  2239. P_Right = P_Right->link;
  2240. }
  2241. /* now perform the dropouts _after_ the span drawing -- */
  2242. /* drop-outs processing has been moved out of the loop */
  2243. /* for performance tuning */
  2244. if ( dropouts > 0 )
  2245. goto Scan_DropOuts;
  2246. Next_Line:
  2247. ras.Proc_Sweep_Step( RAS_VAR );
  2248. y++;
  2249. if ( y < y_change )
  2250. {
  2251. Sort( &draw_left );
  2252. Sort( &draw_right );
  2253. }
  2254. }
  2255. /* Now finalize the profiles that needs it */
  2256. P = draw_left;
  2257. while ( P )
  2258. {
  2259. Q = P->link;
  2260. if ( P->height == 0 )
  2261. DelOld( &draw_left, P );
  2262. P = Q;
  2263. }
  2264. P = draw_right;
  2265. while ( P )
  2266. {
  2267. Q = P->link;
  2268. if ( P->height == 0 )
  2269. DelOld( &draw_right, P );
  2270. P = Q;
  2271. }
  2272. }
  2273. /* for gray-scaling, flushes the bitmap scanline cache */
  2274. while ( y <= max_Y )
  2275. {
  2276. ras.Proc_Sweep_Step( RAS_VAR );
  2277. y++;
  2278. }
  2279. return SUCCESS;
  2280. Scan_DropOuts:
  2281. P_Left = draw_left;
  2282. P_Right = draw_right;
  2283. while ( P_Left )
  2284. {
  2285. if ( P_Left->countL )
  2286. {
  2287. P_Left->countL = 0;
  2288. #if 0
  2289. dropouts--; /* -- this is useful when debugging only */
  2290. #endif
  2291. ras.Proc_Sweep_Drop( RAS_VARS y,
  2292. P_Left->X,
  2293. P_Right->X,
  2294. P_Left,
  2295. P_Right );
  2296. }
  2297. P_Left = P_Left->link;
  2298. P_Right = P_Right->link;
  2299. }
  2300. goto Next_Line;
  2301. }
  2302. /*************************************************************************/
  2303. /* */
  2304. /* <Function> */
  2305. /* Render_Single_Pass */
  2306. /* */
  2307. /* <Description> */
  2308. /* Performs one sweep with sub-banding. */
  2309. /* */
  2310. /* <Input> */
  2311. /* flipped :: If set, flip the direction of the outline. */
  2312. /* */
  2313. /* <Return> */
  2314. /* Renderer error code. */
  2315. /* */
  2316. static int
  2317. Render_Single_Pass( RAS_ARGS Bool flipped )
  2318. {
  2319. Short i, j, k;
  2320. while ( ras.band_top >= 0 )
  2321. {
  2322. ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision;
  2323. ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision;
  2324. ras.top = ras.buff;
  2325. ras.error = Raster_Err_None;
  2326. if ( Convert_Glyph( RAS_VARS flipped ) )
  2327. {
  2328. if ( ras.error != Raster_Err_Overflow )
  2329. return FAILURE;
  2330. ras.error = Raster_Err_None;
  2331. /* sub-banding */
  2332. #ifdef DEBUG_RASTER
  2333. ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) );
  2334. #endif
  2335. i = ras.band_stack[ras.band_top].y_min;
  2336. j = ras.band_stack[ras.band_top].y_max;
  2337. k = (Short)( ( i + j ) / 2 );
  2338. if ( ras.band_top >= 7 || k < i )
  2339. {
  2340. ras.band_top = 0;
  2341. ras.error = Raster_Err_Invalid;
  2342. return ras.error;
  2343. }
  2344. ras.band_stack[ras.band_top + 1].y_min = k;
  2345. ras.band_stack[ras.band_top + 1].y_max = j;
  2346. ras.band_stack[ras.band_top].y_max = (Short)( k - 1 );
  2347. ras.band_top++;
  2348. }
  2349. else
  2350. {
  2351. if ( ras.fProfile )
  2352. if ( Draw_Sweep( RAS_VAR ) )
  2353. return ras.error;
  2354. ras.band_top--;
  2355. }
  2356. }
  2357. return SUCCESS;
  2358. }
  2359. /*************************************************************************/
  2360. /* */
  2361. /* <Function> */
  2362. /* Render_Glyph */
  2363. /* */
  2364. /* <Description> */
  2365. /* Renders a glyph in a bitmap. Sub-banding if needed. */
  2366. /* */
  2367. /* <Return> */
  2368. /* FreeType error code. 0 means success. */
  2369. /* */
  2370. FT_LOCAL_DEF( FT_Error )
  2371. Render_Glyph( RAS_ARG )
  2372. {
  2373. FT_Error error;
  2374. Set_High_Precision( RAS_VARS ras.outline.flags &
  2375. FT_OUTLINE_HIGH_PRECISION );
  2376. ras.scale_shift = ras.precision_shift;
  2377. ras.dropOutControl = 2;
  2378. ras.second_pass = (FT_Byte)( !( ras.outline.flags &
  2379. FT_OUTLINE_SINGLE_PASS ) );
  2380. /* Vertical Sweep */
  2381. ras.Proc_Sweep_Init = Vertical_Sweep_Init;
  2382. ras.Proc_Sweep_Span = Vertical_Sweep_Span;
  2383. ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
  2384. ras.Proc_Sweep_Step = Vertical_Sweep_Step;
  2385. ras.band_top = 0;
  2386. ras.band_stack[0].y_min = 0;
  2387. ras.band_stack[0].y_max = (short)( ras.target.rows - 1 );
  2388. ras.bWidth = (unsigned short)ras.target.width;
  2389. ras.bTarget = (Byte*)ras.target.buffer;
  2390. if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 )
  2391. return error;
  2392. /* Horizontal Sweep */
  2393. if ( ras.second_pass && ras.dropOutControl != 0 )
  2394. {
  2395. ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
  2396. ras.Proc_Sweep_Span = Horizontal_Sweep_Span;
  2397. ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;
  2398. ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
  2399. ras.band_top = 0;
  2400. ras.band_stack[0].y_min = 0;
  2401. ras.band_stack[0].y_max = (short)( ras.target.width - 1 );
  2402. if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 )
  2403. return error;
  2404. }
  2405. return Raster_Err_Ok;
  2406. }
  2407. #ifdef FT_RASTER_OPTION_ANTI_ALIASING
  2408. /*************************************************************************/
  2409. /* */
  2410. /* <Function> */
  2411. /* Render_Gray_Glyph */
  2412. /* */
  2413. /* <Description> */
  2414. /* Renders a glyph with grayscaling. Sub-banding if needed. */
  2415. /* */
  2416. /* <Return> */
  2417. /* FreeType error code. 0 means success. */
  2418. /* */
  2419. FT_LOCAL_DEF( FT_Error )
  2420. Render_Gray_Glyph( RAS_ARG )
  2421. {
  2422. Long pixel_width;
  2423. FT_Error error;
  2424. Set_High_Precision( RAS_VARS ras.outline.flags &
  2425. FT_OUTLINE_HIGH_PRECISION );
  2426. ras.scale_shift = ras.precision_shift + 1;
  2427. ras.dropOutControl = 2;
  2428. ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
  2429. /* Vertical Sweep */
  2430. ras.band_top = 0;
  2431. ras.band_stack[0].y_min = 0;
  2432. ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
  2433. ras.bWidth = ras.gray_width;
  2434. pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );
  2435. if ( ras.bWidth > pixel_width )
  2436. ras.bWidth = pixel_width;
  2437. ras.bWidth = ras.bWidth * 8;
  2438. ras.bTarget = (Byte*)ras.gray_lines;
  2439. ras.gTarget = (Byte*)ras.target.buffer;
  2440. ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;
  2441. ras.Proc_Sweep_Span = Vertical_Sweep_Span;
  2442. ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
  2443. ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;
  2444. error = Render_Single_Pass( RAS_VARS 0 );
  2445. if ( error )
  2446. return error;
  2447. /* Horizontal Sweep */
  2448. if ( ras.second_pass && ras.dropOutControl != 0 )
  2449. {
  2450. ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
  2451. ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
  2452. ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;
  2453. ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
  2454. ras.band_top = 0;
  2455. ras.band_stack[0].y_min = 0;
  2456. ras.band_stack[0].y_max = ras.target.width * 2 - 1;
  2457. error = Render_Single_Pass( RAS_VARS 1 );
  2458. if ( error )
  2459. return error;
  2460. }
  2461. return Raster_Err_Ok;
  2462. }
  2463. #else /* !FT_RASTER_OPTION_ANTI_ALIASING */
  2464. FT_LOCAL_DEF( FT_Error )
  2465. Render_Gray_Glyph( RAS_ARG )
  2466. {
  2467. FT_UNUSED_RASTER;
  2468. return Raster_Err_Cannot_Render_Glyph;
  2469. }
  2470. #endif /* !FT_RASTER_OPTION_ANTI_ALIASING */
  2471. static void
  2472. ft_black_init( TRaster_Instance* raster )
  2473. {
  2474. FT_UInt n;
  2475. FT_ULong c;
  2476. /* setup count table */
  2477. for ( n = 0; n < 256; n++ )
  2478. {
  2479. c = ( n & 0x55 ) + ( ( n & 0xAA ) >> 1 );
  2480. c = ( ( c << 6 ) & 0x3000 ) |
  2481. ( ( c << 4 ) & 0x0300 ) |
  2482. ( ( c << 2 ) & 0x0030 ) |
  2483. (c & 0x0003 );
  2484. raster->count_table[n] = (UInt)c;
  2485. }
  2486. #ifdef FT_RASTER_OPTION_ANTI_ALIASING
  2487. /* set default 5-levels gray palette */
  2488. for ( n = 0; n < 5; n++ )
  2489. raster->grays[n] = n * 255 / 4;
  2490. raster->gray_width = RASTER_GRAY_LINES / 2;
  2491. #endif
  2492. }
  2493. /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/
  2494. /**** a static object. *****/
  2495. #ifdef _STANDALONE_
  2496. static int
  2497. ft_black_new( void* memory,
  2498. FT_Raster *araster )
  2499. {
  2500. static FT_RasterRec_ the_raster;
  2501. *araster = &the_raster;
  2502. FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
  2503. ft_black_init( &the_raster );
  2504. return 0;
  2505. }
  2506. static void
  2507. ft_black_done( FT_Raster raster )
  2508. {
  2509. /* nothing */
  2510. raster->init = 0;
  2511. }
  2512. #else /* _STANDALONE_ */
  2513. static int
  2514. ft_black_new( FT_Memory memory,
  2515. TRaster_Instance** araster )
  2516. {
  2517. FT_Error error;
  2518. TRaster_Instance* raster;
  2519. *araster = 0;
  2520. if ( !FT_NEW( raster ) )
  2521. {
  2522. raster->memory = memory;
  2523. ft_black_init( raster );
  2524. *araster = raster;
  2525. }
  2526. return error;
  2527. }
  2528. static void
  2529. ft_black_done( TRaster_Instance* raster )
  2530. {
  2531. FT_Memory memory = (FT_Memory)raster->memory;
  2532. FT_FREE( raster );
  2533. }
  2534. #endif /* _STANDALONE_ */
  2535. static void
  2536. ft_black_reset( TRaster_Instance* raster,
  2537. const char* pool_base,
  2538. long pool_size )
  2539. {
  2540. if ( raster && pool_base && pool_size >= 4096 )
  2541. {
  2542. /* save the pool */
  2543. raster->buff = (PLong)pool_base;
  2544. raster->sizeBuff = raster->buff + pool_size / sizeof ( Long );
  2545. }
  2546. }
  2547. static void
  2548. ft_black_set_mode( TRaster_Instance* raster,
  2549. unsigned long mode,
  2550. const char* palette )
  2551. {
  2552. #ifdef FT_RASTER_OPTION_ANTI_ALIASING
  2553. if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
  2554. {
  2555. /* set 5-levels gray palette */
  2556. raster->grays[0] = palette[0];
  2557. raster->grays[1] = palette[1];
  2558. raster->grays[2] = palette[2];
  2559. raster->grays[3] = palette[3];
  2560. raster->grays[4] = palette[4];
  2561. }
  2562. #else
  2563. FT_UNUSED( raster );
  2564. FT_UNUSED( mode );
  2565. FT_UNUSED( palette );
  2566. #endif
  2567. }
  2568. static int
  2569. ft_black_render( TRaster_Instance* raster,
  2570. FT_Raster_Params* params )
  2571. {
  2572. FT_Outline* outline = (FT_Outline*)params->source;
  2573. FT_Bitmap* target_map = params->target;
  2574. if ( !raster || !raster->buff || !raster->sizeBuff )
  2575. return Raster_Err_Not_Ini;
  2576. /* return immediately if the outline is empty */
  2577. if ( outline->n_points == 0 || outline->n_contours <= 0 )
  2578. return Raster_Err_None;
  2579. if ( !outline || !outline->contours || !outline->points )
  2580. return Raster_Err_Invalid;
  2581. if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 )
  2582. return Raster_Err_Invalid;
  2583. /* this version of the raster does not support direct rendering, sorry */
  2584. if ( params->flags & FT_RASTER_FLAG_DIRECT )
  2585. return Raster_Err_Unsupported;
  2586. if ( !target_map || !target_map->buffer )
  2587. return Raster_Err_Invalid;
  2588. ras.outline = *outline;
  2589. ras.target = *target_map;
  2590. return ( ( params->flags & FT_RASTER_FLAG_AA )
  2591. ? Render_Gray_Glyph( raster )
  2592. : Render_Glyph( raster ) );
  2593. }
  2594. const FT_Raster_Funcs ft_standard_raster =
  2595. {
  2596. FT_GLYPH_FORMAT_OUTLINE,
  2597. (FT_Raster_New_Func) ft_black_new,
  2598. (FT_Raster_Reset_Func) ft_black_reset,
  2599. (FT_Raster_Set_Mode_Func)ft_black_set_mode,
  2600. (FT_Raster_Render_Func) ft_black_render,
  2601. (FT_Raster_Done_Func) ft_black_done
  2602. };
  2603. /* END */