mupdf.ts 115 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408
  1. // Copyright (C) 2004-2025 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF WASM Library.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. "use strict"
  23. import { Pointer } from "./mupdf-wasm.js"
  24. import libmupdf_wasm from "./mupdf-wasm.js"
  25. declare global {
  26. var $libmupdf_wasm_Module: any
  27. }
  28. var node_fs: any = null
  29. if (typeof process !== "undefined" && process.versions && process.versions.node)
  30. node_fs = await import("node:fs")
  31. const libmupdf = await libmupdf_wasm(globalThis["$libmupdf_wasm_Module"])
  32. libmupdf._wasm_init_context()
  33. function Malloc<T>(size: number) {
  34. return libmupdf._wasm_malloc(size) as unknown as Pointer<T>
  35. }
  36. function Free(ptr: any) {
  37. libmupdf._wasm_free(ptr as Pointer<"void">)
  38. }
  39. export const memento = {
  40. listBlocks() {
  41. libmupdf._wasm_Memento_listBlocks()
  42. },
  43. checkAllMemory() {
  44. libmupdf._wasm_Memento_checkAllMemory()
  45. },
  46. }
  47. /*
  48. --------------------------------------------------------------------------------
  49. How to call into WASM and convert values between JS and WASM (libmupdf) worlds:
  50. Passing values into WASM needs to either copy primitive values into WASM memory
  51. or passing around pointer values.
  52. Wrap and/or copy non-Userdata values into WASM:
  53. STRING(stringValue)
  54. STRING2(stringValue) -- if you need to pass more than one string
  55. MATRIX(matrixArray)
  56. RECT(rectArray)
  57. BUFFER(bufferValue)
  58. etc.
  59. Look up an enum value by string:
  60. ENUM<EnumType>(string, listOfValidValues)
  61. Pass the pointer when the value is a Userdata object:
  62. userdataObject.pointer
  63. Convert WASM pointer into a JS value (for simple types like strings and matrices).
  64. fromType(pointer)
  65. Wrap a WASM pointer in a new Userdata object (for complex types):
  66. new Wrapper(pointer)
  67. PDFObjects are always bound to a PDFDocument, so must be accessed via a document:
  68. doc._fromPDFObjectNew(new_ptr)
  69. doc._fromPDFObjectKeep(borrowed_ptr)
  70. doc._PDFOBJ(value)
  71. Type checking of input arguments at runtime.
  72. checkType(value, "string")
  73. checkType(value, Class)
  74. checkRect(value)
  75. checkMatrix(value)
  76. This code needs to work type safely from plain Javascript too,
  77. so do NOT rely on Typescript to do all the type checking.
  78. --------------------------------------------------------------------------------
  79. */
  80. export type Matrix = [number, number, number, number, number, number]
  81. export type Rect = [number, number, number, number]
  82. export type Quad = [number, number, number, number, number, number, number, number]
  83. export type Point = [number, number]
  84. export type Color = [number] | [number, number, number] | [number, number, number, number]
  85. export type Rotate = 0 | 90 | 180 | 270
  86. export const Matrix = {
  87. identity: [ 1, 0, 0, 1, 0, 0 ] as Matrix,
  88. scale(sx: number, sy: number): Matrix {
  89. return [ sx, 0, 0, sy, 0, 0 ]
  90. },
  91. translate(tx: number, ty: number): Matrix {
  92. return [ 1, 0, 0, 1, tx, ty ]
  93. },
  94. rotate(d: number): Matrix {
  95. while (d < 0)
  96. d += 360
  97. while (d >= 360)
  98. d -= 360
  99. let s = Math.sin((d * Math.PI) / 180)
  100. let c = Math.cos((d * Math.PI) / 180)
  101. return [ c, s, -s, c, 0, 0 ]
  102. },
  103. invert(m: Matrix): Matrix {
  104. checkMatrix(m)
  105. let det = m[0] * m[3] - m[1] * m[2]
  106. if (det > -1e-23 && det < 1e-23)
  107. return m
  108. let rdet = 1 / det
  109. let inva = m[3] * rdet
  110. let invb = -m[1] * rdet
  111. let invc = -m[2] * rdet
  112. let invd = m[0] * rdet
  113. let inve = -m[4] * inva - m[5] * invc
  114. let invf = -m[4] * invb - m[5] * invd
  115. return [ inva, invb, invc, invd, inve, invf ]
  116. },
  117. concat(one: Matrix, two: Matrix): Matrix {
  118. checkMatrix(one)
  119. checkMatrix(two)
  120. return [
  121. one[0] * two[0] + one[1] * two[2],
  122. one[0] * two[1] + one[1] * two[3],
  123. one[2] * two[0] + one[3] * two[2],
  124. one[2] * two[1] + one[3] * two[3],
  125. one[4] * two[0] + one[5] * two[2] + two[4],
  126. one[4] * two[1] + one[5] * two[3] + two[5],
  127. ]
  128. },
  129. }
  130. export const Rect = {
  131. MIN_INF_RECT: 0x80000000,
  132. MAX_INF_RECT: 0x7fffff80,
  133. isEmpty: function (rect: Rect) {
  134. checkRect(rect)
  135. return rect[0] >= rect[2] || rect[1] >= rect[3]
  136. },
  137. isValid: function (rect: Rect) {
  138. checkRect(rect)
  139. return rect[0] <= rect[2] && rect[1] <= rect[3]
  140. },
  141. isInfinite: function (rect: Rect) {
  142. checkRect(rect)
  143. return (
  144. rect[0] === Rect.MAX_INF_RECT &&
  145. rect[1] === Rect.MAX_INF_RECT &&
  146. rect[2] === Rect.MIN_INF_RECT &&
  147. rect[3] === Rect.MIN_INF_RECT
  148. )
  149. },
  150. transform: function (rect: Rect, matrix: Matrix): Rect {
  151. checkRect(rect)
  152. checkMatrix(matrix)
  153. var t
  154. if (Rect.isInfinite(rect))
  155. return rect
  156. if (!Rect.isValid(rect))
  157. return rect
  158. var ax0 = rect[0] * matrix[0]
  159. var ax1 = rect[2] * matrix[0]
  160. if (ax0 > ax1)
  161. t = ax0, ax0 = ax1, ax1 = t
  162. var cy0 = rect[1] * matrix[2]
  163. var cy1 = rect[3] * matrix[2]
  164. if (cy0 > cy1)
  165. t = cy0, cy0 = cy1, cy1 = t
  166. ax0 += cy0 + matrix[4]
  167. ax1 += cy1 + matrix[4]
  168. var bx0 = rect[0] * matrix[1]
  169. var bx1 = rect[2] * matrix[1]
  170. if (bx0 > bx1)
  171. t = bx0, bx0 = bx1, bx1 = t
  172. var dy0 = rect[1] * matrix[3]
  173. var dy1 = rect[3] * matrix[3]
  174. if (dy0 > dy1)
  175. t = dy0, dy0 = dy1, dy1 = t
  176. bx0 += dy0 + matrix[5]
  177. bx1 += dy1 + matrix[5]
  178. return [ ax0, bx0, ax1, bx1 ]
  179. },
  180. }
  181. export function enableICC() {
  182. libmupdf._wasm_enable_icc()
  183. }
  184. export function disableICC() {
  185. libmupdf._wasm_disable_icc()
  186. }
  187. export function setUserCSS(text: string) {
  188. libmupdf._wasm_set_user_css(STRING(text))
  189. }
  190. export function installLoadFontFunction(f: (name: string, script: string, bold: boolean, italic: boolean) => Font | null) {
  191. $libmupdf_load_font_file_js = f
  192. }
  193. /* -------------------------------------------------------------------------- */
  194. // To pass Rect and Matrix as pointer arguments
  195. const _wasm_int = Malloc<"int">(4)
  196. const _wasm_point = Malloc<"fz_point">(4 * 6) >> 2
  197. const _wasm_rect = Malloc<"fz_rect">(4 * 8) >> 2
  198. const _wasm_matrix = Malloc<"fz_matrix">(4 * 6) >> 2
  199. const _wasm_color = Malloc<"number">(4 * 4) >> 2
  200. const _wasm_quad = Malloc<"fz_quad">(4 * 8) >> 2
  201. const _wasm_string: [ Pointer<"char">, Pointer<"char"> ] = [ 0 as Pointer<"char">, 0 as Pointer<"char"> ]
  202. function checkType(value: any, type: any) {
  203. if (typeof type === "string" && typeof value !== type)
  204. throw new TypeError("expected " + type)
  205. if (typeof type === "function" && !(value instanceof type))
  206. throw new TypeError("expected " + type.name)
  207. }
  208. function checkPoint(value: any): asserts value is Point {
  209. if (!Array.isArray(value) || value.length !== 2)
  210. throw new TypeError("expected point")
  211. }
  212. function checkRect(value: any): asserts value is Rect {
  213. if (!Array.isArray(value) || value.length !== 4)
  214. throw new TypeError("expected rectangle")
  215. }
  216. function checkMatrix(value: any): asserts value is Matrix {
  217. if (!Array.isArray(value) || value.length !== 6)
  218. throw new TypeError("expected matrix")
  219. }
  220. function checkQuad(value: any): asserts value is Quad {
  221. if (!Array.isArray(value) || value.length !== 8)
  222. throw new TypeError("expected quad")
  223. }
  224. function checkColor(value: any): asserts value is Color {
  225. if (!Array.isArray(value) || (value.length !== 1 && value.length !== 3 && value.length !== 4))
  226. throw new TypeError("expected color array")
  227. }
  228. /** The types that can be automatically converted into a Buffer object */
  229. type AnyBuffer = Buffer | ArrayBuffer | Uint8Array | string
  230. function BUFFER(input: AnyBuffer) {
  231. if (input instanceof Buffer)
  232. return input.pointer
  233. if (input instanceof ArrayBuffer || input instanceof Uint8Array)
  234. return new Buffer(input).pointer
  235. if (typeof input === "string")
  236. return new Buffer(input).pointer
  237. throw new TypeError("expected buffer")
  238. }
  239. function ENUM<T>(value: T, list: readonly T[]): number {
  240. if (typeof value === "number") {
  241. if (value >= 0 && value < list.length)
  242. return value
  243. }
  244. if (typeof value === "string") {
  245. let idx = list.indexOf(value)
  246. if (idx >= 0)
  247. return idx
  248. }
  249. throw new TypeError(`invalid enum value ("${value}"; expected ${list.join(", ")})`)
  250. }
  251. function allocateUTF8(str: string) {
  252. var size = libmupdf.lengthBytesUTF8(str) + 1
  253. var pointer = Malloc<"XXX">(size) as unknown as Pointer<"char">
  254. libmupdf.stringToUTF8(str, pointer, size)
  255. return pointer
  256. }
  257. function STRING_N(s: string, i: number) {
  258. if (_wasm_string[i]) {
  259. Free(_wasm_string[i])
  260. _wasm_string[i] = 0 as Pointer<"char">
  261. }
  262. return _wasm_string[i] = allocateUTF8(s)
  263. }
  264. function STRING(s: string) {
  265. return STRING_N(s, 0)
  266. }
  267. function STRING2(s: string) {
  268. return STRING_N(s, 1)
  269. }
  270. function STRING_OPT(s: string | null | undefined) {
  271. return typeof s === "string" ? STRING_N(s, 0) : 0 as Pointer<"char">
  272. }
  273. function STRING2_OPT(s: string | null | undefined) {
  274. return typeof s === "string" ? STRING_N(s, 1) : 0 as Pointer<"char">
  275. }
  276. function POINT(p: Point) {
  277. libmupdf.HEAPF32[_wasm_point + 0] = p[0]
  278. libmupdf.HEAPF32[_wasm_point + 1] = p[1]
  279. return _wasm_point << 2 as Pointer<"fz_point">
  280. }
  281. function POINT2(p: Point) {
  282. libmupdf.HEAPF32[_wasm_point + 2] = p[0]
  283. libmupdf.HEAPF32[_wasm_point + 3] = p[1]
  284. return (_wasm_point + 2) << 2 as Pointer<"fz_point">
  285. }
  286. function POINT3(p: Point) {
  287. libmupdf.HEAPF32[_wasm_point + 4] = p[0]
  288. libmupdf.HEAPF32[_wasm_point + 5] = p[1]
  289. return (_wasm_point + 4) << 2 as Pointer<"fz_point">
  290. }
  291. function RECT(r: Rect) {
  292. libmupdf.HEAPF32[_wasm_rect + 0] = r[0]
  293. libmupdf.HEAPF32[_wasm_rect + 1] = r[1]
  294. libmupdf.HEAPF32[_wasm_rect + 2] = r[2]
  295. libmupdf.HEAPF32[_wasm_rect + 3] = r[3]
  296. return _wasm_rect << 2 as Pointer<"fz_rect">
  297. }
  298. function RECT2(r: Rect) {
  299. libmupdf.HEAPF32[_wasm_rect + 4] = r[0]
  300. libmupdf.HEAPF32[_wasm_rect + 5] = r[1]
  301. libmupdf.HEAPF32[_wasm_rect + 6] = r[2]
  302. libmupdf.HEAPF32[_wasm_rect + 7] = r[3]
  303. return (_wasm_rect + 4) << 2 as Pointer<"fz_rect">
  304. }
  305. function MATRIX(m: Matrix) {
  306. libmupdf.HEAPF32[_wasm_matrix + 0] = m[0]
  307. libmupdf.HEAPF32[_wasm_matrix + 1] = m[1]
  308. libmupdf.HEAPF32[_wasm_matrix + 2] = m[2]
  309. libmupdf.HEAPF32[_wasm_matrix + 3] = m[3]
  310. libmupdf.HEAPF32[_wasm_matrix + 4] = m[4]
  311. libmupdf.HEAPF32[_wasm_matrix + 5] = m[5]
  312. return _wasm_matrix << 2 as Pointer<"fz_matrix">
  313. }
  314. function QUAD(q: Quad) {
  315. libmupdf.HEAPF32[_wasm_quad + 0] = q[0]
  316. libmupdf.HEAPF32[_wasm_quad + 1] = q[1]
  317. libmupdf.HEAPF32[_wasm_quad + 2] = q[2]
  318. libmupdf.HEAPF32[_wasm_quad + 3] = q[3]
  319. libmupdf.HEAPF32[_wasm_quad + 4] = q[4]
  320. libmupdf.HEAPF32[_wasm_quad + 5] = q[5]
  321. libmupdf.HEAPF32[_wasm_quad + 6] = q[6]
  322. libmupdf.HEAPF32[_wasm_quad + 7] = q[7]
  323. return _wasm_quad << 2 as Pointer<"fz_quad">
  324. }
  325. function COLOR(c?: Color) {
  326. if (typeof c !== "undefined") {
  327. switch (c.length) {
  328. case 1:
  329. libmupdf.HEAPF32[_wasm_color + 0] = c[0]
  330. break
  331. case 3:
  332. libmupdf.HEAPF32[_wasm_color + 0] = c[0]
  333. libmupdf.HEAPF32[_wasm_color + 1] = c[1]
  334. libmupdf.HEAPF32[_wasm_color + 2] = c[2]
  335. break
  336. case 4:
  337. libmupdf.HEAPF32[_wasm_color + 0] = c[0]
  338. libmupdf.HEAPF32[_wasm_color + 1] = c[1]
  339. libmupdf.HEAPF32[_wasm_color + 2] = c[2]
  340. libmupdf.HEAPF32[_wasm_color + 3] = c[3]
  341. break
  342. }
  343. }
  344. return _wasm_color << 2 as Pointer<"float">
  345. }
  346. /* -------------------------------------------------------------------------- */
  347. function fromColor(n: number): Color {
  348. if (n === 1)
  349. return [
  350. libmupdf.HEAPF32[_wasm_color] as number
  351. ]
  352. if (n === 3)
  353. return [
  354. libmupdf.HEAPF32[_wasm_color + 0] as number,
  355. libmupdf.HEAPF32[_wasm_color + 1] as number,
  356. libmupdf.HEAPF32[_wasm_color + 2] as number,
  357. ]
  358. if (n === 4)
  359. return [
  360. libmupdf.HEAPF32[_wasm_color + 0] as number,
  361. libmupdf.HEAPF32[_wasm_color + 1] as number,
  362. libmupdf.HEAPF32[_wasm_color + 2] as number,
  363. libmupdf.HEAPF32[_wasm_color + 3] as number,
  364. ]
  365. throw new TypeError("invalid number of components for Color: " + n)
  366. }
  367. function fromColorArray(n: number, ptr: Pointer<"float">): number[] {
  368. let addr = ptr >> 2
  369. let color: number[] = []
  370. for (let i = 0; i < n; ++i)
  371. color.push(libmupdf.HEAPF32[addr + i] as number)
  372. return color
  373. }
  374. function fromString(ptr: Pointer<"char">): string {
  375. return libmupdf.UTF8ToString(ptr)
  376. }
  377. function fromStringFree(ptr: Pointer<"char">): string {
  378. let str = libmupdf.UTF8ToString(ptr)
  379. Free(ptr)
  380. return str
  381. }
  382. function fromPoint(ptr: Pointer<"fz_point">): Point {
  383. let addr = ptr >> 2
  384. return [
  385. libmupdf.HEAPF32[addr + 0] as number,
  386. libmupdf.HEAPF32[addr + 1] as number,
  387. ]
  388. }
  389. function fromRect(ptr: Pointer<"fz_rect">): Rect {
  390. let addr = ptr >> 2
  391. return [
  392. libmupdf.HEAPF32[addr + 0] as number,
  393. libmupdf.HEAPF32[addr + 1] as number,
  394. libmupdf.HEAPF32[addr + 2] as number,
  395. libmupdf.HEAPF32[addr + 3] as number,
  396. ]
  397. }
  398. function fromMatrix(ptr: Pointer<"fz_matrix">): Matrix {
  399. let addr = ptr >> 2
  400. return [
  401. libmupdf.HEAPF32[addr + 0] as number,
  402. libmupdf.HEAPF32[addr + 1] as number,
  403. libmupdf.HEAPF32[addr + 2] as number,
  404. libmupdf.HEAPF32[addr + 3] as number,
  405. libmupdf.HEAPF32[addr + 4] as number,
  406. libmupdf.HEAPF32[addr + 5] as number,
  407. ]
  408. }
  409. function fromQuad(ptr: Pointer<"fz_quad">): Quad {
  410. let addr = ptr >> 2
  411. return [
  412. libmupdf.HEAPF32[addr + 0] as number,
  413. libmupdf.HEAPF32[addr + 1] as number,
  414. libmupdf.HEAPF32[addr + 2] as number,
  415. libmupdf.HEAPF32[addr + 3] as number,
  416. libmupdf.HEAPF32[addr + 4] as number,
  417. libmupdf.HEAPF32[addr + 5] as number,
  418. libmupdf.HEAPF32[addr + 6] as number,
  419. libmupdf.HEAPF32[addr + 7] as number,
  420. ]
  421. }
  422. function fromBuffer(ptr: Pointer<"fz_buffer">): Uint8Array {
  423. let data = libmupdf._wasm_buffer_get_data(ptr)
  424. let size = libmupdf._wasm_buffer_get_len(ptr)
  425. return libmupdf.HEAPU8.slice(data, data + size)
  426. }
  427. /* unused for now
  428. function rgbFromColor(c?: Color): [number, number, number] {
  429. var r = 0, g = 0, b = 0
  430. if (typeof c !== "undefined") {
  431. switch (c.length) {
  432. case 1:
  433. r = g = b = c[0]
  434. break
  435. case 3:
  436. r = c[0]
  437. g = c[1]
  438. b = c[2]
  439. break
  440. case 4:
  441. r = 1 - Math.min(1, c[0] + c[3])
  442. g = 1 - Math.min(1, c[1] + c[3])
  443. b = 1 - Math.min(1, c[2] + c[3])
  444. break
  445. }
  446. }
  447. return [ r, g, b ]
  448. }
  449. function numberFromColor(c?: Color): number {
  450. var [ r, g, b ] = rgbFromColor(c)
  451. return (255 << 24) | (r << 16) | (g << 8) | b
  452. }
  453. */
  454. function colorFromNumber(argb: number): Color {
  455. var r = (argb >> 16) & 255
  456. var g = (argb >> 8) & 255
  457. var b = (argb) & 255
  458. return [ r / 255, g / 255, b / 255 ]
  459. }
  460. /* -------------------------------------------------------------------------- */
  461. type SearchFunction = (
  462. display_list: any,
  463. needle: Pointer<"char">,
  464. marks: Pointer<"int">,
  465. hits: Pointer<"fz_quad">,
  466. hit_max: number
  467. ) => number
  468. function runSearch(searchFun: SearchFunction, searchThis: number, needle: string, max_hits = 500) {
  469. checkType(needle, "string")
  470. let hits = 0 as Pointer<"fz_quad">
  471. let marks = 0 as Pointer<"int">
  472. try {
  473. hits = Malloc<"fz_quad">(32 * max_hits)
  474. marks = Malloc<"int">(4 * max_hits)
  475. let n = searchFun(searchThis as any, STRING(needle), marks, hits, max_hits)
  476. let outer: Quad[][] = []
  477. if (n > 0) {
  478. let inner: Quad[] = []
  479. for (let i = 0; i < n; ++i) {
  480. let mark = libmupdf.HEAP32[(marks>>2) + i]
  481. let quad = fromQuad(hits + i * 32 as Pointer<"fz_quad">)
  482. if (i > 0 && mark) {
  483. outer.push(inner)
  484. inner = []
  485. }
  486. inner.push(quad)
  487. }
  488. outer.push(inner)
  489. }
  490. return outer
  491. } finally {
  492. Free(marks)
  493. Free(hits)
  494. }
  495. }
  496. /* -------------------------------------------------------------------------- */
  497. abstract class Userdata<B> {
  498. private static _finalizer: FinalizationRegistry<number>
  499. static readonly _drop: (pointer: any) => void
  500. pointer: Pointer<B>
  501. constructor(pointer: Pointer<B>) {
  502. if (typeof pointer !== "number")
  503. throw new Error("invalid pointer: " + typeof pointer)
  504. if (pointer !== 0) {
  505. let ctor = this.constructor as typeof Userdata
  506. if (!ctor._finalizer)
  507. ctor._finalizer = new FinalizationRegistry(ctor._drop)
  508. ctor._finalizer.register(this, pointer, this)
  509. }
  510. this.pointer = pointer
  511. }
  512. destroy() {
  513. if (this.pointer !== 0) {
  514. let ctor = this.constructor as typeof Userdata
  515. ctor._finalizer.unregister(this)
  516. ctor._drop(this.pointer)
  517. }
  518. this.pointer = 0 as Pointer<B>
  519. }
  520. // Custom "console.log" formatting for Node
  521. [Symbol.for("nodejs.util.inspect.custom")]() {
  522. return this.toString()
  523. }
  524. toString() {
  525. return `[${this.constructor.name} ${this.pointer}]`
  526. }
  527. valueOf() {
  528. throw new Error("cannot convert Userdata to Javascript value")
  529. }
  530. }
  531. export class Buffer extends Userdata<"fz_buffer"> {
  532. static override readonly _drop = libmupdf._wasm_drop_buffer
  533. /** New empty Buffer. */
  534. constructor()
  535. /** New Buffer initialized with string contents as UTF-8. */
  536. constructor(data: string)
  537. /** New Buffer initialized with typed array contents. */
  538. constructor(data: ArrayBuffer | Uint8Array)
  539. /** PRIVATE */
  540. constructor(pointer: Pointer<"fz_buffer">)
  541. constructor(arg?: Pointer<"fz_buffer"> | string | ArrayBuffer | Uint8Array) {
  542. if (typeof arg === "undefined")
  543. super(libmupdf._wasm_new_buffer(1024))
  544. else if (typeof arg === "number")
  545. super(arg)
  546. else if (typeof arg === "string") {
  547. let data_len = libmupdf.lengthBytesUTF8(arg)
  548. let data_ptr = Malloc<"char">(data_len + 1)
  549. libmupdf.stringToUTF8(arg, data_ptr, data_len + 1)
  550. super(libmupdf._wasm_new_buffer_from_data(data_ptr, data_len))
  551. }
  552. else if (arg instanceof ArrayBuffer || arg instanceof Uint8Array) {
  553. let data_len = arg.byteLength
  554. let data_ptr = Malloc<"char">(data_len)
  555. libmupdf.HEAPU8.set(new Uint8Array(arg), data_ptr)
  556. super(libmupdf._wasm_new_buffer_from_data(data_ptr, data_len))
  557. }
  558. }
  559. getLength() {
  560. return libmupdf._wasm_buffer_get_len(this.pointer)
  561. }
  562. readByte(at: number) {
  563. let data = libmupdf._wasm_buffer_get_data(this.pointer)
  564. return libmupdf.HEAPU8[data + at] as number
  565. }
  566. write(s: string) {
  567. libmupdf._wasm_append_string(this.pointer, STRING(s))
  568. }
  569. writeByte(b: number) {
  570. libmupdf._wasm_append_byte(this.pointer, b)
  571. }
  572. writeLine(s: string) {
  573. this.write(s)
  574. this.writeByte(10)
  575. }
  576. writeBuffer(other: AnyBuffer) {
  577. libmupdf._wasm_append_buffer(this.pointer, BUFFER(other))
  578. }
  579. asUint8Array() {
  580. let data = libmupdf._wasm_buffer_get_data(this.pointer)
  581. let size = libmupdf._wasm_buffer_get_len(this.pointer)
  582. return libmupdf.HEAPU8.subarray(data, data + size)
  583. }
  584. slice(start: number, end: number) {
  585. return new Buffer(libmupdf._wasm_slice_buffer(this.pointer, start, end))
  586. }
  587. asString() {
  588. return fromString(libmupdf._wasm_string_from_buffer(this.pointer))
  589. }
  590. save(filename: string) {
  591. if (node_fs)
  592. node_fs.writeFileSync(filename, this.asUint8Array())
  593. else
  594. throw new Error("missing 'fs' module")
  595. }
  596. }
  597. export type ColorSpaceType =
  598. "None" |
  599. "Gray" |
  600. "RGB" |
  601. "BGR" |
  602. "CMYK" |
  603. "Lab" |
  604. "Indexed" |
  605. "Separation"
  606. export class ColorSpace extends Userdata<"fz_colorspace"> {
  607. static override readonly _drop = libmupdf._wasm_drop_colorspace
  608. static readonly COLORSPACE_TYPES: ColorSpaceType[] = [
  609. "None",
  610. "Gray",
  611. "RGB",
  612. "BGR",
  613. "CMYK",
  614. "Lab",
  615. "Indexed",
  616. "Separation"
  617. ]
  618. // Create ColorSpace from ICC profile.
  619. constructor(profile: AnyBuffer, name: string)
  620. // PRIVATE
  621. constructor(pointer: Pointer<"fz_colorspace">)
  622. constructor(from: Pointer<"fz_colorspace"> | AnyBuffer, name?: string) {
  623. if (typeof from === "number")
  624. super(from)
  625. else
  626. super(libmupdf._wasm_new_icc_colorspace(STRING_OPT(name), BUFFER(from)))
  627. }
  628. getName() {
  629. return fromString(libmupdf._wasm_colorspace_get_name(this.pointer))
  630. }
  631. getType() {
  632. return ColorSpace.COLORSPACE_TYPES[libmupdf._wasm_colorspace_get_type(this.pointer)] || "None"
  633. }
  634. getNumberOfComponents() {
  635. return libmupdf._wasm_colorspace_get_n(this.pointer)
  636. }
  637. isGray(): boolean { return this.getType() === "Gray" }
  638. isRGB(): boolean { return this.getType() === "RGB" }
  639. isCMYK(): boolean { return this.getType() === "CMYK" }
  640. isIndexed(): boolean { return this.getType() === "Indexed" }
  641. isLab(): boolean { return this.getType() === "Lab" }
  642. isDeviceN(): boolean { return this.getType() === "Separation" }
  643. isSubtractive(): boolean { return this.getType() === "CMYK" || this.getType() === "Separation" }
  644. override toString() {
  645. return "[ColorSpace " + this.getName() + "]"
  646. }
  647. static readonly DeviceGray = new ColorSpace(libmupdf._wasm_device_gray())
  648. static readonly DeviceRGB = new ColorSpace(libmupdf._wasm_device_rgb())
  649. static readonly DeviceBGR = new ColorSpace(libmupdf._wasm_device_bgr())
  650. static readonly DeviceCMYK = new ColorSpace(libmupdf._wasm_device_cmyk())
  651. static readonly Lab = new ColorSpace(libmupdf._wasm_device_lab())
  652. }
  653. export type FontSimpleEncoding = "Latin" | "Greek" | "Cyrillic"
  654. export type FontCJKOrdering = 0 | 1 | 2 | 3
  655. export type FontCJKLanguage =
  656. "Adobe-CNS1" |
  657. "Adobe-GB1" |
  658. "Adobe-Japan1" |
  659. "Adobe-Korea1" |
  660. "zh-Hant" |
  661. "zh-TW" |
  662. "zh-HK" |
  663. "zh-Hans" |
  664. "zh-CN" |
  665. "ja" |
  666. "ko"
  667. export class Font extends Userdata<"fz_font"> {
  668. static override readonly _drop = libmupdf._wasm_drop_font
  669. static readonly SIMPLE_ENCODING: FontSimpleEncoding[] = [
  670. "Latin",
  671. "Greek",
  672. "Cyrillic"
  673. ]
  674. static readonly ADOBE_CNS = 0
  675. static readonly ADOBE_GB = 1
  676. static readonly ADOBE_JAPAN = 2
  677. static readonly ADOBE_KOREA = 3
  678. static readonly CJK_ORDERING_BY_LANG: Record<FontCJKLanguage,FontCJKOrdering> = {
  679. "Adobe-CNS1": 0,
  680. "Adobe-GB1": 1,
  681. "Adobe-Japan1": 2,
  682. "Adobe-Korea1": 3,
  683. "zh-Hant": 0,
  684. "zh-TW": 0,
  685. "zh-HK": 0,
  686. "zh-Hans": 1,
  687. "zh-CN": 1,
  688. "ja": 2,
  689. "ko": 3,
  690. }
  691. constructor(name: string)
  692. constructor(name: string, filename: string, subfont?: number)
  693. constructor(name: string, data: AnyBuffer, subfont?: number)
  694. constructor(pointer: Pointer<"fz_font">)
  695. constructor(name_or_pointer: Pointer<"fz_font"> | string, data?: AnyBuffer, subfont=0) {
  696. let pointer = 0 as Pointer<"fz_font">
  697. if (typeof name_or_pointer === "number") {
  698. pointer = libmupdf._wasm_keep_font(name_or_pointer)
  699. } else {
  700. if (typeof data === "string") {
  701. if (node_fs)
  702. data = node_fs.readFileSync(data)
  703. else
  704. throw new Error("missing 'fs' module")
  705. }
  706. if (data)
  707. pointer = libmupdf._wasm_new_font_from_buffer(STRING(name_or_pointer), BUFFER(data), subfont)
  708. else if (name_or_pointer === "zh-Hant")
  709. pointer = libmupdf._wasm_new_cjk_font(Font.ADOBE_CNS)
  710. else if (name_or_pointer === "zh-Hans")
  711. pointer = libmupdf._wasm_new_cjk_font(Font.ADOBE_GB)
  712. else if (name_or_pointer === "ja")
  713. pointer = libmupdf._wasm_new_cjk_font(Font.ADOBE_JAPAN)
  714. else if (name_or_pointer === "ko")
  715. pointer = libmupdf._wasm_new_cjk_font(Font.ADOBE_KOREA)
  716. else
  717. pointer = libmupdf._wasm_new_base14_font(STRING(name_or_pointer))
  718. }
  719. super(pointer)
  720. }
  721. getName() {
  722. return fromString(libmupdf._wasm_font_get_name(this.pointer))
  723. }
  724. encodeCharacter(uni: number | string) {
  725. if (typeof uni === "string")
  726. uni = uni.charCodeAt(0)
  727. return libmupdf._wasm_encode_character(this.pointer, uni)
  728. }
  729. advanceGlyph(gid: number, wmode = 0) {
  730. return libmupdf._wasm_advance_glyph(this.pointer, gid, wmode)
  731. }
  732. isMono() {
  733. return !!libmupdf._wasm_font_is_monospaced(this.pointer)
  734. }
  735. isSerif() {
  736. return !!libmupdf._wasm_font_is_serif(this.pointer)
  737. }
  738. isBold() {
  739. return !!libmupdf._wasm_font_is_bold(this.pointer)
  740. }
  741. isItalic() {
  742. return !!libmupdf._wasm_font_is_italic(this.pointer)
  743. }
  744. }
  745. export class Image extends Userdata<"fz_image"> {
  746. static override readonly _drop = libmupdf._wasm_drop_image
  747. constructor(pointer: Pointer<"fz_image">)
  748. constructor(filename: string)
  749. constructor(data: AnyBuffer)
  750. constructor(pixmap: Pixmap, mask?: Image)
  751. constructor(data: Pointer<"fz_image"> | Pixmap | AnyBuffer, mask?: Image) {
  752. let pointer = 0 as Pointer<"fz_image">
  753. if (typeof data === "number") {
  754. pointer = libmupdf._wasm_keep_image(data)
  755. } else if (data instanceof Pixmap) {
  756. pointer = libmupdf._wasm_new_image_from_pixmap(
  757. data.pointer,
  758. mask ? mask.pointer : 0 as Pointer<"fz_image">
  759. )
  760. } else {
  761. if (typeof data === "string") {
  762. if (node_fs)
  763. data = node_fs.readFileSync(data)
  764. else
  765. throw new Error("missing 'fs' module")
  766. }
  767. pointer = libmupdf._wasm_new_image_from_buffer(BUFFER(data as Uint8Array))
  768. }
  769. super(pointer)
  770. }
  771. getWidth() {
  772. return libmupdf._wasm_image_get_w(this.pointer)
  773. }
  774. getHeight() {
  775. return libmupdf._wasm_image_get_h(this.pointer)
  776. }
  777. getNumberOfComponents() {
  778. return libmupdf._wasm_image_get_n(this.pointer)
  779. }
  780. getBitsPerComponent() {
  781. return libmupdf._wasm_image_get_bpc(this.pointer)
  782. }
  783. getXResolution() {
  784. return libmupdf._wasm_image_get_xres(this.pointer)
  785. }
  786. getYResolution() {
  787. return libmupdf._wasm_image_get_yres(this.pointer)
  788. }
  789. getImageMask() {
  790. return !!libmupdf._wasm_image_get_imagemask(this.pointer)
  791. }
  792. getColorSpace() {
  793. let cs = libmupdf._wasm_image_get_colorspace(this.pointer)
  794. if (cs)
  795. return new ColorSpace(libmupdf._wasm_keep_colorspace(cs))
  796. return null
  797. }
  798. getMask() {
  799. let mask = libmupdf._wasm_image_get_mask(this.pointer)
  800. if (mask)
  801. return new Image(libmupdf._wasm_keep_image(mask))
  802. return null
  803. }
  804. toPixmap() {
  805. return new Pixmap(libmupdf._wasm_get_pixmap_from_image(this.pointer))
  806. }
  807. }
  808. export type LineCap = "Butt" | "Round" | "Square" | "Triangle"
  809. export type LineJoin = "Miter" | "Round" | "Bevel" | "MiterXPS"
  810. // TODO: convert StrokeState from plain JS object to match mutool run ffi_pushstroke/ffi_tostroke
  811. export type StrokeStateData = {
  812. lineCap: LineCap,
  813. lineJoin: LineJoin,
  814. lineWidth: number,
  815. miterLimit: number,
  816. dashPhase?: number,
  817. dashes?: number[],
  818. }
  819. export class StrokeState extends Userdata<"fz_stroke_state"> {
  820. static override readonly _drop = libmupdf._wasm_drop_stroke_state
  821. static readonly LINE_CAP: LineCap[] = [
  822. "Butt",
  823. "Round",
  824. "Square",
  825. "Triangle"
  826. ]
  827. static readonly LINE_JOIN: LineJoin[] = [
  828. "Miter",
  829. "Round",
  830. "Bevel",
  831. "MiterXPS"
  832. ]
  833. constructor(data: Pointer<"fz_stroke_state"> | StrokeStateData) {
  834. if (typeof data === "number") {
  835. super(data)
  836. return this
  837. }
  838. super(libmupdf._wasm_new_stroke_state(data?.dashes?.length ?? 0))
  839. let lineCap = ENUM<LineCap>(data.lineCap, StrokeState.LINE_CAP)
  840. let lineJoin = ENUM<LineJoin>(data.lineJoin, StrokeState.LINE_JOIN)
  841. libmupdf._wasm_stroke_state_set_start_cap(this.pointer, lineCap)
  842. libmupdf._wasm_stroke_state_set_dash_cap(this.pointer, lineCap)
  843. libmupdf._wasm_stroke_state_set_end_cap(this.pointer, lineCap)
  844. libmupdf._wasm_stroke_state_set_linejoin(this.pointer, lineJoin)
  845. libmupdf._wasm_stroke_state_set_linewidth(this.pointer, data.lineWidth)
  846. libmupdf._wasm_stroke_state_set_miterlimit(this.pointer, data.miterLimit)
  847. libmupdf._wasm_stroke_state_set_dash_phase(this.pointer, data.dashPhase ?? 0)
  848. if (data.dashes) {
  849. for (let i = 0; i < data.dashes.length; ++i)
  850. libmupdf._wasm_stroke_state_set_dash_item(this.pointer, i, data.dashes[i] ?? 0)
  851. }
  852. }
  853. getLineCap() {
  854. return libmupdf._wasm_stroke_state_get_start_cap(this.pointer)
  855. }
  856. getLineJoin() {
  857. return libmupdf._wasm_stroke_state_get_linejoin(this.pointer)
  858. }
  859. getLineWidth() {
  860. return libmupdf._wasm_stroke_state_get_linewidth(this.pointer)
  861. }
  862. getMiterLimit() {
  863. return libmupdf._wasm_stroke_state_get_miterlimit(this.pointer)
  864. }
  865. getDashPhase() {
  866. return libmupdf._wasm_stroke_state_get_dash_phase(this.pointer)
  867. }
  868. getDashes(): number[] | null {
  869. var n = libmupdf._wasm_stroke_state_get_dash_len(this.pointer)
  870. if (n > 0) {
  871. var out: number[] = []
  872. for (let i = 0; i < n; ++i)
  873. out[i] = libmupdf._wasm_stroke_state_get_dash_item(this.pointer, i)
  874. return out
  875. }
  876. return null
  877. }
  878. }
  879. interface PathWalker {
  880. moveTo?(x: number, y: number): void
  881. lineTo?(x: number, y: number): void
  882. curveTo?(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void
  883. closePath?(): void
  884. }
  885. export class Path extends Userdata<"fz_path"> {
  886. static override readonly _drop = libmupdf._wasm_drop_path
  887. constructor(pointer?: Pointer<"fz_path">) {
  888. if (typeof pointer === "number")
  889. super(pointer)
  890. else
  891. super(libmupdf._wasm_new_path())
  892. }
  893. getBounds(strokeState: StrokeState, transform: Matrix) {
  894. if (strokeState !== null)
  895. checkType(strokeState, StrokeState)
  896. checkMatrix(transform)
  897. return fromRect(libmupdf._wasm_bound_path(this.pointer, strokeState?.pointer, MATRIX(transform)))
  898. }
  899. moveTo(x: number, y: number) {
  900. checkType(x, "number")
  901. checkType(y, "number")
  902. libmupdf._wasm_moveto(this.pointer, x, y)
  903. }
  904. lineTo(x: number, y: number) {
  905. checkType(x, "number")
  906. checkType(y, "number")
  907. libmupdf._wasm_lineto(this.pointer, x, y)
  908. }
  909. curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number) {
  910. libmupdf._wasm_curveto(this.pointer, x1, y1, x2, y2, x3, y3)
  911. }
  912. curveToV(cx: number, cy: number, ex: number, ey: number) {
  913. libmupdf._wasm_curvetov(this.pointer, cx, cy, ex, ey)
  914. }
  915. curveToY(cx: number, cy: number, ex: number, ey: number) {
  916. libmupdf._wasm_curvetoy(this.pointer, cx, cy, ex, ey)
  917. }
  918. closePath() {
  919. libmupdf._wasm_closepath(this.pointer)
  920. }
  921. rect(x1: number, y1: number, x2: number, y2: number) {
  922. libmupdf._wasm_rectto(this.pointer, x1, y1, x2, y2)
  923. }
  924. transform(matrix: Matrix) {
  925. checkMatrix(matrix)
  926. libmupdf._wasm_transform_path(this.pointer, MATRIX(matrix))
  927. }
  928. walk(walker: PathWalker) {
  929. let id = $libmupdf_path_id++
  930. $libmupdf_path_table.set(id, walker)
  931. libmupdf._wasm_walk_path(this.pointer, id)
  932. $libmupdf_path_table.delete(id)
  933. }
  934. }
  935. interface TextWalker {
  936. beginSpan?(font: Font, trm: Matrix, wmode: number, bidi: number, markupDirection: number, language: string): void
  937. showGlyph?(font: Font, trm: Matrix, glyph: number, unicode: number, wmode: number, bidi: number): void
  938. endSpan?(): void
  939. }
  940. export class Text extends Userdata<"fz_text"> {
  941. static override readonly _drop = libmupdf._wasm_drop_text
  942. constructor(pointer?: Pointer<"fz_text">) {
  943. if (typeof pointer === "number")
  944. super(pointer)
  945. else
  946. super(libmupdf._wasm_new_text())
  947. }
  948. getBounds(strokeState: StrokeState, transform: Matrix) {
  949. if (strokeState !== null)
  950. checkType(strokeState, StrokeState)
  951. checkMatrix(transform)
  952. return fromRect(libmupdf._wasm_bound_text(this.pointer, strokeState?.pointer, MATRIX(transform)))
  953. }
  954. showGlyph(font: Font, trm: Matrix, gid: number, uni: number, wmode = 0) {
  955. checkType(font, Font)
  956. checkMatrix(trm)
  957. checkType(gid, "number")
  958. checkType(uni, "number")
  959. libmupdf._wasm_show_glyph(
  960. this.pointer,
  961. font.pointer,
  962. MATRIX(trm),
  963. gid,
  964. uni,
  965. wmode
  966. )
  967. }
  968. showString(font: Font, trm: Matrix, str: string, wmode = 0) {
  969. checkType(font, Font)
  970. checkMatrix(trm)
  971. checkType(str, "string")
  972. return fromMatrix(
  973. libmupdf._wasm_show_string(
  974. this.pointer,
  975. font.pointer,
  976. MATRIX(trm),
  977. STRING(str),
  978. wmode
  979. )
  980. )
  981. }
  982. walk(walker: TextWalker) {
  983. let id = $libmupdf_text_id++
  984. $libmupdf_text_table.set(id, walker)
  985. libmupdf._wasm_walk_text(this.pointer, id)
  986. $libmupdf_text_table.delete(id)
  987. }
  988. }
  989. export class DisplayList extends Userdata<"fz_display_list"> {
  990. static override readonly _drop = libmupdf._wasm_drop_display_list
  991. constructor(pointer: Pointer<"fz_display_list">)
  992. constructor(mediabox: Rect)
  993. constructor(arg1: Pointer<"fz_display_list"> | Rect) {
  994. let pointer = 0 as Pointer<"fz_display_list">
  995. if (typeof arg1 === "number") {
  996. pointer = arg1
  997. } else {
  998. checkRect(arg1)
  999. pointer = libmupdf._wasm_new_display_list(RECT(arg1))
  1000. }
  1001. super(pointer)
  1002. }
  1003. getBounds() {
  1004. return fromRect(libmupdf._wasm_bound_display_list(this.pointer))
  1005. }
  1006. toPixmap(matrix: Matrix, colorspace: ColorSpace, alpha = false) {
  1007. checkMatrix(matrix)
  1008. checkType(colorspace, ColorSpace)
  1009. return new Pixmap(
  1010. libmupdf._wasm_new_pixmap_from_display_list(
  1011. this.pointer,
  1012. MATRIX(matrix),
  1013. colorspace.pointer,
  1014. alpha
  1015. )
  1016. )
  1017. }
  1018. toStructuredText(options = "") {
  1019. checkType(options, "string")
  1020. return new StructuredText(libmupdf._wasm_new_stext_page_from_display_list(this.pointer, STRING(options)))
  1021. }
  1022. run(device: Device, matrix: Matrix) {
  1023. checkType(device, Device)
  1024. checkMatrix(matrix)
  1025. libmupdf._wasm_run_display_list(this.pointer, device.pointer, MATRIX(matrix))
  1026. }
  1027. search(needle: string, max_hits = 500) {
  1028. return runSearch(libmupdf._wasm_search_display_list, this.pointer, needle, max_hits)
  1029. }
  1030. }
  1031. export class Pixmap extends Userdata<"fz_pixmap"> {
  1032. static override readonly _drop = libmupdf._wasm_drop_pixmap
  1033. constructor(pointer: Pointer<"fz_pixmap">)
  1034. constructor(colorspace: ColorSpace, bbox: Rect, alpha: boolean)
  1035. constructor(arg1: Pointer<"fz_pixmap"> | ColorSpace, bbox?: Rect, alpha = false) {
  1036. if (typeof arg1 === "number") {
  1037. super(arg1)
  1038. }
  1039. if (arg1 instanceof ColorSpace) {
  1040. checkRect(bbox)
  1041. super(libmupdf._wasm_new_pixmap_with_bbox(arg1.pointer, RECT(bbox), alpha))
  1042. }
  1043. if (arg1 === null) {
  1044. checkRect(bbox)
  1045. super(libmupdf._wasm_new_pixmap_with_bbox(0 as Pointer<"fz_colorspace">, RECT(bbox), alpha))
  1046. }
  1047. }
  1048. getBounds() {
  1049. let x = libmupdf._wasm_pixmap_get_x(this.pointer)
  1050. let y = libmupdf._wasm_pixmap_get_y(this.pointer)
  1051. let w = libmupdf._wasm_pixmap_get_w(this.pointer)
  1052. let h = libmupdf._wasm_pixmap_get_h(this.pointer)
  1053. return [ x, y, x + w, y + h ]
  1054. }
  1055. clear(value?: number) {
  1056. if (typeof value === "undefined")
  1057. libmupdf._wasm_clear_pixmap(this.pointer)
  1058. else
  1059. libmupdf._wasm_clear_pixmap_with_value(this.pointer, value)
  1060. }
  1061. getWidth() {
  1062. return libmupdf._wasm_pixmap_get_w(this.pointer)
  1063. }
  1064. getHeight() {
  1065. return libmupdf._wasm_pixmap_get_h(this.pointer)
  1066. }
  1067. getX() {
  1068. return libmupdf._wasm_pixmap_get_x(this.pointer)
  1069. }
  1070. getY() {
  1071. return libmupdf._wasm_pixmap_get_y(this.pointer)
  1072. }
  1073. getStride() {
  1074. return libmupdf._wasm_pixmap_get_stride(this.pointer)
  1075. }
  1076. getNumberOfComponents() {
  1077. return libmupdf._wasm_pixmap_get_n(this.pointer)
  1078. }
  1079. getAlpha() {
  1080. return libmupdf._wasm_pixmap_get_alpha(this.pointer)
  1081. }
  1082. getXResolution() {
  1083. return libmupdf._wasm_pixmap_get_xres(this.pointer)
  1084. }
  1085. getYResolution() {
  1086. return libmupdf._wasm_pixmap_get_yres(this.pointer)
  1087. }
  1088. setResolution(x: number, y: number) {
  1089. libmupdf._wasm_pixmap_set_xres(this.pointer, x)
  1090. libmupdf._wasm_pixmap_set_yres(this.pointer, y)
  1091. }
  1092. getColorSpace() {
  1093. let cs = libmupdf._wasm_pixmap_get_colorspace(this.pointer)
  1094. if (cs)
  1095. return new ColorSpace(libmupdf._wasm_keep_colorspace(cs))
  1096. return null
  1097. }
  1098. getPixels() {
  1099. let s = libmupdf._wasm_pixmap_get_stride(this.pointer)
  1100. let h = libmupdf._wasm_pixmap_get_h(this.pointer)
  1101. let p = libmupdf._wasm_pixmap_get_samples(this.pointer)
  1102. return new Uint8ClampedArray(libmupdf.HEAPU8.buffer, p, s * h)
  1103. }
  1104. asPNG() {
  1105. let buf = libmupdf._wasm_new_buffer_from_pixmap_as_png(this.pointer)
  1106. try {
  1107. return fromBuffer(buf)
  1108. } finally {
  1109. libmupdf._wasm_drop_buffer(buf)
  1110. }
  1111. }
  1112. asPSD() {
  1113. let buf = libmupdf._wasm_new_buffer_from_pixmap_as_psd(this.pointer)
  1114. try {
  1115. return fromBuffer(buf)
  1116. } finally {
  1117. libmupdf._wasm_drop_buffer(buf)
  1118. }
  1119. }
  1120. asPAM() {
  1121. let buf = libmupdf._wasm_new_buffer_from_pixmap_as_pam(this.pointer)
  1122. try {
  1123. return fromBuffer(buf)
  1124. } finally {
  1125. libmupdf._wasm_drop_buffer(buf)
  1126. }
  1127. }
  1128. asJPEG(quality: number, invert_cmyk: boolean) {
  1129. let buf = libmupdf._wasm_new_buffer_from_pixmap_as_jpeg(this.pointer, quality, invert_cmyk)
  1130. try {
  1131. return fromBuffer(buf)
  1132. } finally {
  1133. libmupdf._wasm_drop_buffer(buf)
  1134. }
  1135. }
  1136. invert() {
  1137. libmupdf._wasm_invert_pixmap(this.pointer)
  1138. }
  1139. invertLuminance() {
  1140. libmupdf._wasm_invert_pixmap_luminance(this.pointer)
  1141. }
  1142. gamma(p: number) {
  1143. libmupdf._wasm_gamma_pixmap(this.pointer, p)
  1144. }
  1145. tint(black: number | Color, white: number | Color) {
  1146. let black_hex = 0x000000
  1147. let white_hex = 0xffffff
  1148. if (typeof black === "number")
  1149. black_hex = black
  1150. else if (black instanceof Array && black.length === 3)
  1151. black_hex = ( ( (black[0] * 255) << 16 ) | ( (black[1] * 255) << 8 ) | ( (black[2] * 255) ) )
  1152. if (typeof white === "number")
  1153. white_hex = white
  1154. else if (white instanceof Array && white.length === 3)
  1155. white = ( ( (white[0] * 255) << 16 ) | ( (white[1] * 255) << 8 ) | ( (white[2] * 255) ) )
  1156. libmupdf._wasm_tint_pixmap(this.pointer, black_hex, white_hex)
  1157. }
  1158. convertToColorSpace(colorspace: ColorSpace, keepAlpha=false) {
  1159. checkType(colorspace, ColorSpace)
  1160. checkType(keepAlpha, "boolean")
  1161. return new Pixmap(libmupdf._wasm_convert_pixmap(this.pointer, colorspace.pointer, keepAlpha))
  1162. }
  1163. warp(points: Point[], width: number, height: number) {
  1164. let quad = points.flat()
  1165. checkQuad(quad)
  1166. checkType(width, "number")
  1167. checkType(height, "number")
  1168. return new Pixmap(libmupdf._wasm_warp_pixmap(this.pointer, QUAD(quad), width, height))
  1169. }
  1170. }
  1171. export class Shade extends Userdata<"fz_shade"> {
  1172. static override readonly _drop = libmupdf._wasm_drop_shade
  1173. getBounds() {
  1174. return fromRect(libmupdf._wasm_bound_shade(this.pointer))
  1175. }
  1176. }
  1177. interface StructuredTextWalker {
  1178. onImageBlock?(bbox: Rect, transform: Matrix, image: Image): void
  1179. beginTextBlock?(bbox: Rect): void
  1180. beginLine?(bbox: Rect, wmode: number, direction: Point): void
  1181. onChar?(c: string, origin: Point, font: Font, size: number, quad: Quad, color: Color): void
  1182. endLine?(): void
  1183. endTextBlock?(): void
  1184. }
  1185. type SelectMode = "chars" | "words" | "lines"
  1186. export class StructuredText extends Userdata<"fz_stext_page"> {
  1187. static override readonly _drop = libmupdf._wasm_drop_stext_page
  1188. static readonly SELECT_MODE: SelectMode[] = [
  1189. "chars",
  1190. "words",
  1191. "lines"
  1192. ]
  1193. static readonly SELECT_CHARS = "chars"
  1194. static readonly SELECT_WORDS = "words"
  1195. static readonly SELECT_LINES = "lines"
  1196. walk(walker: StructuredTextWalker) {
  1197. let block = libmupdf._wasm_stext_page_get_first_block(this.pointer)
  1198. while (block) {
  1199. let block_type = libmupdf._wasm_stext_block_get_type(block)
  1200. let block_bbox = fromRect(libmupdf._wasm_stext_block_get_bbox(block))
  1201. if (block_type === 1) {
  1202. if (walker.onImageBlock) {
  1203. let matrix = fromMatrix(libmupdf._wasm_stext_block_get_transform(block))
  1204. let image = new Image(libmupdf._wasm_stext_block_get_image(block))
  1205. walker.onImageBlock(block_bbox, matrix, image)
  1206. }
  1207. } else {
  1208. if (walker.beginTextBlock)
  1209. walker.beginTextBlock(block_bbox)
  1210. let line = libmupdf._wasm_stext_block_get_first_line(block)
  1211. while (line) {
  1212. let line_bbox = fromRect(libmupdf._wasm_stext_line_get_bbox(line))
  1213. let line_wmode = libmupdf._wasm_stext_line_get_wmode(line)
  1214. let line_dir = fromPoint(libmupdf._wasm_stext_line_get_dir(line))
  1215. if (walker.beginLine)
  1216. walker.beginLine(line_bbox, line_wmode, line_dir)
  1217. if (walker.onChar) {
  1218. let ch = libmupdf._wasm_stext_line_get_first_char(line)
  1219. while (ch) {
  1220. let ch_rune = String.fromCharCode(libmupdf._wasm_stext_char_get_c(ch))
  1221. let ch_origin = fromPoint(libmupdf._wasm_stext_char_get_origin(ch))
  1222. let ch_font = new Font(libmupdf._wasm_stext_char_get_font(ch))
  1223. let ch_size = libmupdf._wasm_stext_char_get_size(ch)
  1224. let ch_quad = fromQuad(libmupdf._wasm_stext_char_get_quad(ch))
  1225. let ch_color = colorFromNumber(libmupdf._wasm_stext_char_get_argb(ch))
  1226. walker.onChar(ch_rune, ch_origin, ch_font, ch_size, ch_quad, ch_color)
  1227. ch = libmupdf._wasm_stext_char_get_next(ch)
  1228. }
  1229. }
  1230. if (walker.endLine)
  1231. walker.endLine()
  1232. line = libmupdf._wasm_stext_line_get_next(line)
  1233. }
  1234. if (walker.endTextBlock)
  1235. walker.endTextBlock()
  1236. }
  1237. block = libmupdf._wasm_stext_block_get_next(block)
  1238. }
  1239. }
  1240. asJSON(scale = 1) {
  1241. return fromStringFree(libmupdf._wasm_print_stext_page_as_json(this.pointer, scale))
  1242. }
  1243. asHTML(id: number) {
  1244. return fromStringFree(libmupdf._wasm_print_stext_page_as_html(this.pointer, id))
  1245. }
  1246. asText() {
  1247. return fromStringFree(libmupdf._wasm_print_stext_page_as_text(this.pointer))
  1248. }
  1249. snap(p: Point, q: Point, mode: SelectMode): Quad {
  1250. let mm = ENUM<SelectMode>(mode, StructuredText.SELECT_MODE)
  1251. return fromQuad(libmupdf._wasm_snap_selection(this.pointer, POINT(p), POINT2(q), mm))
  1252. }
  1253. copy(p: Point, q: Point): string {
  1254. return fromStringFree(libmupdf._wasm_copy_selection(this.pointer, POINT(p), POINT2(q)))
  1255. }
  1256. highlight(p: Point, q: Point, max_hits = 100): Quad[] {
  1257. let hits = 0 as Pointer<"fz_quad">
  1258. let result: Quad[] = []
  1259. try {
  1260. hits = Malloc<"fz_quad">(32 * max_hits)
  1261. let n = libmupdf._wasm_highlight_selection(this.pointer, POINT(p), POINT2(q), hits, max_hits)
  1262. for (let i = 0; i < n; ++i)
  1263. result.push(fromQuad(hits + i * 32 as Pointer<"fz_quad">))
  1264. } finally {
  1265. Free(hits)
  1266. }
  1267. return result
  1268. }
  1269. search(needle: string, max_hits = 500) {
  1270. return runSearch(libmupdf._wasm_search_stext_page, this.pointer, needle, max_hits)
  1271. }
  1272. }
  1273. export type BlendMode =
  1274. "Normal" |
  1275. "Multiply" |
  1276. "Screen" |
  1277. "Overlay" |
  1278. "Darken" |
  1279. "Lighten" |
  1280. "ColorDodge" |
  1281. "ColorBurn" |
  1282. "HardLight" |
  1283. "SoftLight" |
  1284. "Difference" |
  1285. "Exclusion" |
  1286. "Hue" |
  1287. "Saturation" |
  1288. "Color" |
  1289. "Luminosity"
  1290. export class Device extends Userdata<"fz_device"> {
  1291. static override readonly _drop = libmupdf._wasm_drop_device
  1292. static readonly BLEND_MODES: BlendMode[] = [
  1293. "Normal",
  1294. "Multiply",
  1295. "Screen",
  1296. "Overlay",
  1297. "Darken",
  1298. "Lighten",
  1299. "ColorDodge",
  1300. "ColorBurn",
  1301. "HardLight",
  1302. "SoftLight",
  1303. "Difference",
  1304. "Exclusion",
  1305. "Hue",
  1306. "Saturation",
  1307. "Color",
  1308. "Luminosity",
  1309. ]
  1310. constructor(pointer: Pointer<"fz_device">)
  1311. constructor(callbacks: DeviceFunctions)
  1312. constructor(pointer_or_callbacks: Pointer<"fz_device"> | DeviceFunctions) {
  1313. if (typeof pointer_or_callbacks === "number")
  1314. super(pointer_or_callbacks)
  1315. else {
  1316. let id = $libmupdf_device_id++
  1317. $libmupdf_device_table.set(id, pointer_or_callbacks)
  1318. super(libmupdf._wasm_new_js_device(id))
  1319. }
  1320. }
  1321. fillPath(path: Path, evenOdd: boolean, ctm: Matrix, colorspace: ColorSpace, color: Color, alpha: number) {
  1322. checkType(path, Path)
  1323. checkMatrix(ctm)
  1324. checkType(colorspace, ColorSpace)
  1325. checkColor(color)
  1326. libmupdf._wasm_fill_path(this.pointer, path.pointer, evenOdd, MATRIX(ctm), colorspace.pointer, COLOR(color), alpha)
  1327. }
  1328. strokePath(path: Path, stroke: StrokeState, ctm: Matrix, colorspace: ColorSpace, color: Color, alpha: number) {
  1329. checkType(path, Path)
  1330. checkType(stroke, StrokeState)
  1331. checkMatrix(ctm)
  1332. checkType(colorspace, ColorSpace)
  1333. checkColor(color)
  1334. libmupdf._wasm_stroke_path(
  1335. this.pointer,
  1336. path.pointer,
  1337. stroke.pointer,
  1338. MATRIX(ctm),
  1339. colorspace.pointer,
  1340. COLOR(color),
  1341. alpha
  1342. )
  1343. }
  1344. clipPath(path: Path, evenOdd: boolean, ctm: Matrix) {
  1345. checkType(path, Path)
  1346. checkMatrix(ctm)
  1347. libmupdf._wasm_clip_path(this.pointer, path.pointer, evenOdd, MATRIX(ctm))
  1348. }
  1349. clipStrokePath(path: Path, stroke: StrokeState, ctm: Matrix) {
  1350. checkType(path, Path)
  1351. checkType(stroke, StrokeState)
  1352. checkMatrix(ctm)
  1353. libmupdf._wasm_clip_stroke_path(this.pointer, path.pointer, stroke.pointer, MATRIX(ctm))
  1354. }
  1355. fillText(text: Text, ctm: Matrix, colorspace: ColorSpace, color: Color, alpha: number) {
  1356. checkType(text, Text)
  1357. checkMatrix(ctm)
  1358. checkType(colorspace, ColorSpace)
  1359. checkColor(color)
  1360. libmupdf._wasm_fill_text(this.pointer, text.pointer, MATRIX(ctm), colorspace.pointer, COLOR(color), alpha)
  1361. }
  1362. strokeText(text: Text, stroke: StrokeState, ctm: Matrix, colorspace: ColorSpace, color: Color, alpha: number) {
  1363. checkType(text, Text)
  1364. checkType(stroke, StrokeState)
  1365. checkMatrix(ctm)
  1366. checkType(colorspace, ColorSpace)
  1367. checkColor(color)
  1368. libmupdf._wasm_stroke_text(
  1369. this.pointer,
  1370. text.pointer,
  1371. stroke.pointer,
  1372. MATRIX(ctm),
  1373. colorspace.pointer,
  1374. COLOR(color),
  1375. alpha
  1376. )
  1377. }
  1378. clipText(text: Text, ctm: Matrix) {
  1379. checkType(text, Text)
  1380. checkMatrix(ctm)
  1381. libmupdf._wasm_clip_text(this.pointer, text.pointer, MATRIX(ctm))
  1382. }
  1383. clipStrokeText(text: Text, stroke: StrokeState, ctm: Matrix) {
  1384. checkType(text, Text)
  1385. checkType(stroke, StrokeState)
  1386. checkMatrix(ctm)
  1387. libmupdf._wasm_clip_stroke_text(this.pointer, text.pointer, stroke.pointer, MATRIX(ctm))
  1388. }
  1389. ignoreText(text: Text, ctm: Matrix) {
  1390. checkType(text, Text)
  1391. checkMatrix(ctm)
  1392. libmupdf._wasm_ignore_text(this.pointer, text.pointer, MATRIX(ctm))
  1393. }
  1394. fillShade(shade: Shade, ctm: Matrix, alpha: number) {
  1395. checkType(shade, Shade)
  1396. checkMatrix(ctm)
  1397. libmupdf._wasm_fill_shade(this.pointer, shade.pointer, MATRIX(ctm), alpha)
  1398. }
  1399. fillImage(image: Image, ctm: Matrix, alpha: number) {
  1400. checkType(image, Image)
  1401. checkMatrix(ctm)
  1402. libmupdf._wasm_fill_image(this.pointer, image.pointer, MATRIX(ctm), alpha)
  1403. }
  1404. fillImageMask(image: Image, ctm: Matrix, colorspace: ColorSpace, color: Color, alpha: number) {
  1405. checkType(image, Image)
  1406. checkMatrix(ctm)
  1407. checkType(colorspace, ColorSpace)
  1408. checkColor(color)
  1409. libmupdf._wasm_fill_image_mask(this.pointer, image.pointer, MATRIX(ctm), colorspace.pointer, COLOR(color), alpha)
  1410. }
  1411. clipImageMask(image: Image, ctm: Matrix) {
  1412. checkType(image, Image)
  1413. checkMatrix(ctm)
  1414. libmupdf._wasm_clip_image_mask(this.pointer, image.pointer, MATRIX(ctm))
  1415. }
  1416. popClip() {
  1417. libmupdf._wasm_pop_clip(this.pointer)
  1418. }
  1419. beginMask(area: Rect, luminosity: boolean, colorspace: ColorSpace, color: Color) {
  1420. checkRect(area)
  1421. checkType(colorspace, ColorSpace)
  1422. checkColor(color)
  1423. libmupdf._wasm_begin_mask(this.pointer, RECT(area), luminosity, colorspace.pointer, COLOR(color))
  1424. }
  1425. endMask() {
  1426. libmupdf._wasm_end_mask(this.pointer)
  1427. }
  1428. beginGroup(area: Rect, colorspace: ColorSpace, isolated: boolean, knockout: boolean, blendmode: BlendMode, alpha: number) {
  1429. checkRect(area)
  1430. checkType(colorspace, ColorSpace)
  1431. let blendmode_ix = ENUM<BlendMode>(blendmode, Device.BLEND_MODES)
  1432. libmupdf._wasm_begin_group(this.pointer, RECT(area), colorspace.pointer, isolated, knockout, blendmode_ix, alpha)
  1433. }
  1434. endGroup() {
  1435. libmupdf._wasm_end_group(this.pointer)
  1436. }
  1437. beginTile(area: Rect, view: Rect, xstep: number, ystep: number, ctm: Matrix, id: number) {
  1438. checkRect(area)
  1439. checkRect(view)
  1440. checkMatrix(ctm)
  1441. return libmupdf._wasm_begin_tile(this.pointer, RECT(area), RECT2(view), xstep, ystep, MATRIX(ctm), id)
  1442. }
  1443. endTile() {
  1444. libmupdf._wasm_end_tile(this.pointer)
  1445. }
  1446. beginLayer(name: string) {
  1447. libmupdf._wasm_begin_layer(this.pointer, STRING(name))
  1448. }
  1449. endLayer() {
  1450. libmupdf._wasm_end_layer(this.pointer)
  1451. }
  1452. close() {
  1453. libmupdf._wasm_close_device(this.pointer)
  1454. }
  1455. }
  1456. export class DrawDevice extends Device {
  1457. constructor(matrix: Matrix, pixmap: Pixmap) {
  1458. checkMatrix(matrix)
  1459. checkType(pixmap, Pixmap)
  1460. super(libmupdf._wasm_new_draw_device(MATRIX(matrix), pixmap.pointer))
  1461. }
  1462. }
  1463. export class DisplayListDevice extends Device {
  1464. constructor(displayList: DisplayList) {
  1465. checkType(displayList, DisplayList)
  1466. super(libmupdf._wasm_new_display_list_device(displayList.pointer))
  1467. }
  1468. }
  1469. export class DocumentWriter extends Userdata<"fz_document_writer"> {
  1470. static override readonly _drop = libmupdf._wasm_drop_document_writer
  1471. constructor(buffer: Buffer, format: string, options: string) {
  1472. super(
  1473. libmupdf._wasm_new_document_writer_with_buffer(
  1474. BUFFER(buffer),
  1475. STRING(format),
  1476. STRING2(options)
  1477. )
  1478. )
  1479. }
  1480. beginPage(mediabox: Rect) {
  1481. checkRect(mediabox)
  1482. return new Device(libmupdf._wasm_begin_page(this.pointer, RECT(mediabox)))
  1483. }
  1484. endPage() {
  1485. libmupdf._wasm_end_page(this.pointer)
  1486. }
  1487. close() {
  1488. libmupdf._wasm_close_document_writer(this.pointer)
  1489. }
  1490. }
  1491. export type DocumentPermission =
  1492. "print" |
  1493. "copy" |
  1494. "edit" |
  1495. "annotate" |
  1496. "form" |
  1497. "accessibility" |
  1498. "assemble" |
  1499. "print-hq"
  1500. export class Document extends Userdata<"any_document"> {
  1501. static override readonly _drop = libmupdf._wasm_drop_document
  1502. static readonly META_FORMAT = "format"
  1503. static readonly META_ENCRYPTION = "encryption"
  1504. static readonly META_INFO_AUTHOR = "info:Author"
  1505. static readonly META_INFO_TITLE = "info:Title"
  1506. static readonly META_INFO_SUBJECT = "info:Subject"
  1507. static readonly META_INFO_KEYWORDS = "info:Keywords"
  1508. static readonly META_INFO_CREATOR = "info:Creator"
  1509. static readonly META_INFO_PRODUCER = "info:Producer"
  1510. static readonly META_INFO_CREATIONDATE = "info:CreationDate"
  1511. static readonly META_INFO_MODIFICATIONDATE = "info:ModDate"
  1512. static readonly PERMISSION: Record<DocumentPermission,number> = {
  1513. "print": "p".charCodeAt(0),
  1514. "copy": "c".charCodeAt(0),
  1515. "edit": "e".charCodeAt(0),
  1516. "annotate": "n".charCodeAt(0),
  1517. "form": "f".charCodeAt(0),
  1518. "accessibility": "y".charCodeAt(0),
  1519. "assemble": "a".charCodeAt(0),
  1520. "print-hq": "h".charCodeAt(0),
  1521. }
  1522. static readonly LINK_DEST: LinkDestType[] = [
  1523. "Fit",
  1524. "FitB",
  1525. "FitH",
  1526. "FitBH",
  1527. "FitV",
  1528. "FitBV",
  1529. "FitR",
  1530. "XYZ",
  1531. ]
  1532. static openDocument(from: Buffer | ArrayBuffer | Uint8Array | Stream | string, magic?: string): Document {
  1533. let pointer = 0 as Pointer<"any_document">
  1534. if (typeof from === "string") {
  1535. magic = from
  1536. if (node_fs)
  1537. from = node_fs.readFileSync(from)
  1538. else
  1539. throw new Error("missing 'fs' module")
  1540. } else {
  1541. if (typeof magic === "undefined")
  1542. magic = "application/pdf"
  1543. }
  1544. checkType(magic, "string")
  1545. if (from instanceof ArrayBuffer || from instanceof Uint8Array)
  1546. from = new Buffer(from)
  1547. if (from instanceof Buffer)
  1548. pointer = libmupdf._wasm_open_document_with_buffer(STRING(magic), from.pointer)
  1549. else if (from instanceof Stream)
  1550. pointer = libmupdf._wasm_open_document_with_stream(STRING(magic), from.pointer)
  1551. else
  1552. throw new Error("not a Buffer or Stream")
  1553. let pdf = libmupdf._wasm_pdf_document_from_fz_document(pointer)
  1554. if (pdf)
  1555. return new PDFDocument(pdf)
  1556. return new Document(pointer)
  1557. }
  1558. formatLinkURI(dest: LinkDest) {
  1559. return fromStringFree(
  1560. libmupdf._wasm_format_link_uri(this.pointer,
  1561. dest.chapter | 0,
  1562. dest.page | 0,
  1563. ENUM<LinkDestType>(dest.type, Document.LINK_DEST),
  1564. +dest.x,
  1565. +dest.y,
  1566. +dest.width,
  1567. +dest.height,
  1568. +dest.zoom
  1569. )
  1570. )
  1571. }
  1572. isPDF() {
  1573. return this instanceof PDFDocument
  1574. }
  1575. needsPassword() {
  1576. return !!libmupdf._wasm_needs_password(this.pointer)
  1577. }
  1578. authenticatePassword(password: string) {
  1579. return libmupdf._wasm_authenticate_password(this.pointer, STRING(password))
  1580. }
  1581. hasPermission(perm: DocumentPermission) {
  1582. let perm_ix = Document.PERMISSION[perm]
  1583. return !!libmupdf._wasm_has_permission(this.pointer, perm_ix)
  1584. }
  1585. getMetaData(key: string) {
  1586. let value = libmupdf._wasm_lookup_metadata(this.pointer, STRING(key))
  1587. if (value)
  1588. return fromString(value)
  1589. return undefined
  1590. }
  1591. setMetaData(key: string, value: string) {
  1592. libmupdf._wasm_set_metadata(this.pointer, STRING(key), STRING2(value))
  1593. }
  1594. countPages() {
  1595. return libmupdf._wasm_count_pages(this.pointer)
  1596. }
  1597. isReflowable() {
  1598. libmupdf._wasm_is_document_reflowable(this.pointer)
  1599. }
  1600. layout(w: number, h: number, em: number) {
  1601. libmupdf._wasm_layout_document(this.pointer, w, h, em)
  1602. }
  1603. loadPage(index: number) {
  1604. let fz_ptr = libmupdf._wasm_load_page(this.pointer, index)
  1605. if (this instanceof PDFDocument) {
  1606. let pdf_ptr = libmupdf._wasm_pdf_page_from_fz_page(fz_ptr)
  1607. if (pdf_ptr)
  1608. return new PDFPage(this, pdf_ptr)
  1609. }
  1610. return new Page(fz_ptr)
  1611. }
  1612. loadOutline() {
  1613. let doc = this.pointer
  1614. function to_outline(outline: Pointer<"fz_outline">) {
  1615. let result: OutlineItem[] = []
  1616. while (outline) {
  1617. let title = libmupdf._wasm_outline_get_title(outline)
  1618. let uri = libmupdf._wasm_outline_get_uri(outline)
  1619. let open = libmupdf._wasm_outline_get_is_open(outline)
  1620. let item: OutlineItem = {
  1621. title: title ? fromString(title) : undefined,
  1622. uri: uri ? fromString(uri) : undefined,
  1623. open: !!open,
  1624. }
  1625. let page = libmupdf._wasm_outline_get_page(doc, outline)
  1626. if (page >= 0)
  1627. item.page = page
  1628. let down = libmupdf._wasm_outline_get_down(outline)
  1629. if (down)
  1630. item.down = to_outline(down)
  1631. result.push(item)
  1632. outline = libmupdf._wasm_outline_get_next(outline)
  1633. }
  1634. return result
  1635. }
  1636. let root = libmupdf._wasm_load_outline(doc)
  1637. if (root)
  1638. return to_outline(root)
  1639. return null
  1640. }
  1641. resolveLink(link: string | Link) {
  1642. if (link instanceof Link)
  1643. return libmupdf._wasm_resolve_link(this.pointer, libmupdf._wasm_link_get_uri(link.pointer))
  1644. return libmupdf._wasm_resolve_link(this.pointer, STRING(link))
  1645. }
  1646. resolveLinkDestination(link: string | Link): LinkDest {
  1647. let dest: Pointer<"fz_link_dest">
  1648. if (link instanceof Link)
  1649. dest = libmupdf._wasm_resolve_link_dest(this.pointer, libmupdf._wasm_link_get_uri(link.pointer))
  1650. else
  1651. dest = libmupdf._wasm_resolve_link_dest(this.pointer, STRING(link))
  1652. return {
  1653. type: Document.LINK_DEST[libmupdf._wasm_link_dest_get_type(dest)] as LinkDestType,
  1654. chapter: libmupdf._wasm_link_dest_get_chapter(dest),
  1655. page: libmupdf._wasm_link_dest_get_page(dest),
  1656. x: libmupdf._wasm_link_dest_get_x(dest),
  1657. y: libmupdf._wasm_link_dest_get_y(dest),
  1658. width: libmupdf._wasm_link_dest_get_w(dest),
  1659. height: libmupdf._wasm_link_dest_get_h(dest),
  1660. zoom: libmupdf._wasm_link_dest_get_zoom(dest),
  1661. }
  1662. }
  1663. outlineIterator() {
  1664. return new OutlineIterator(libmupdf._wasm_new_outline_iterator(this.pointer))
  1665. }
  1666. }
  1667. interface OutlineItem {
  1668. title: string | undefined,
  1669. uri: string | undefined,
  1670. open: boolean,
  1671. down?: OutlineItem[],
  1672. page?: number,
  1673. }
  1674. export class OutlineIterator extends Userdata<"fz_outline_iterator"> {
  1675. static override readonly _drop = libmupdf._wasm_drop_outline_iterator
  1676. static readonly RESULT_DID_NOT_MOVE = -1
  1677. static readonly RESULT_AT_ITEM = 0
  1678. static readonly RESULT_AT_EMPTY = 1
  1679. item() {
  1680. let item = libmupdf._wasm_outline_iterator_item(this.pointer)
  1681. if (item) {
  1682. let title_ptr = libmupdf._wasm_outline_item_get_title(item)
  1683. let uri_ptr = libmupdf._wasm_outline_item_get_uri(item)
  1684. let is_open = libmupdf._wasm_outline_item_get_is_open(item)
  1685. return {
  1686. title: title_ptr ? fromString(title_ptr) : undefined,
  1687. uri: uri_ptr ? fromString(uri_ptr) : undefined,
  1688. open: !!is_open,
  1689. } as OutlineItem
  1690. }
  1691. return null
  1692. }
  1693. next() {
  1694. return libmupdf._wasm_outline_iterator_next(this.pointer)
  1695. }
  1696. prev() {
  1697. return libmupdf._wasm_outline_iterator_prev(this.pointer)
  1698. }
  1699. up() {
  1700. return libmupdf._wasm_outline_iterator_up(this.pointer)
  1701. }
  1702. down() {
  1703. return libmupdf._wasm_outline_iterator_down(this.pointer)
  1704. }
  1705. delete() {
  1706. return libmupdf._wasm_outline_iterator_delete(this.pointer)
  1707. }
  1708. insert(item: OutlineItem) {
  1709. return libmupdf._wasm_outline_iterator_insert(this.pointer, STRING_OPT(item.title), STRING2_OPT(item.uri), item.open)
  1710. }
  1711. update(item: OutlineItem) {
  1712. libmupdf._wasm_outline_iterator_update(this.pointer, STRING_OPT(item.title), STRING2_OPT(item.uri), item.open)
  1713. }
  1714. }
  1715. export type LinkDestType =
  1716. "Fit" |
  1717. "FitB" |
  1718. "FitH" |
  1719. "FitBH" |
  1720. "FitV" |
  1721. "FitBV" |
  1722. "FitR" |
  1723. "XYZ"
  1724. interface LinkDest {
  1725. type: LinkDestType,
  1726. chapter: number,
  1727. page: number,
  1728. x: number,
  1729. y: number,
  1730. width: number,
  1731. height: number,
  1732. zoom: number,
  1733. }
  1734. export class Link extends Userdata<"fz_link"> {
  1735. static override readonly _drop = libmupdf._wasm_drop_link
  1736. getBounds() {
  1737. return fromRect(libmupdf._wasm_link_get_rect(this.pointer))
  1738. }
  1739. setBounds(rect: Rect) {
  1740. checkRect(rect)
  1741. libmupdf._wasm_link_set_rect(this.pointer, RECT(rect))
  1742. }
  1743. getURI() {
  1744. return fromString(libmupdf._wasm_link_get_uri(this.pointer))
  1745. }
  1746. setURI(uri: string) {
  1747. checkType(uri, "string")
  1748. libmupdf._wasm_link_set_uri(this.pointer, STRING(uri))
  1749. }
  1750. isExternal() {
  1751. return /^\w[\w+-.]*:/.test(this.getURI())
  1752. }
  1753. }
  1754. export type PageBox = "MediaBox" | "CropBox" | "BleedBox" | "TrimBox" | "ArtBox"
  1755. export class Page extends Userdata<"any_page"> {
  1756. static override readonly _drop = libmupdf._wasm_drop_page
  1757. static readonly BOXES: PageBox[] = [
  1758. "MediaBox",
  1759. "CropBox",
  1760. "BleedBox",
  1761. "TrimBox",
  1762. "ArtBox"
  1763. ]
  1764. isPDF() {
  1765. return this instanceof PDFPage
  1766. }
  1767. getBounds(box: PageBox = "CropBox") {
  1768. let box_ix = ENUM<PageBox>(box, Page.BOXES)
  1769. return fromRect(libmupdf._wasm_bound_page(this.pointer, box_ix))
  1770. }
  1771. getLabel() {
  1772. return fromString(libmupdf._wasm_page_label(this.pointer))
  1773. }
  1774. run(device: Device, matrix: Matrix) {
  1775. checkType(device, Device)
  1776. checkMatrix(matrix)
  1777. libmupdf._wasm_run_page(this.pointer, device.pointer, MATRIX(matrix))
  1778. }
  1779. runPageContents(device: Device, matrix: Matrix) {
  1780. checkType(device, Device)
  1781. checkMatrix(matrix)
  1782. libmupdf._wasm_run_page_contents(this.pointer, device.pointer, MATRIX(matrix))
  1783. }
  1784. runPageAnnots(device: Device, matrix: Matrix) {
  1785. checkType(device, Device)
  1786. checkMatrix(matrix)
  1787. libmupdf._wasm_run_page_annots(this.pointer, device.pointer, MATRIX(matrix))
  1788. }
  1789. runPageWidgets(device: Device, matrix: Matrix) {
  1790. checkType(device, Device)
  1791. checkMatrix(matrix)
  1792. libmupdf._wasm_run_page_widgets(this.pointer, device.pointer, MATRIX(matrix))
  1793. }
  1794. toPixmap(matrix: Matrix, colorspace: ColorSpace, alpha = false, showExtras = true) {
  1795. checkType(colorspace, ColorSpace)
  1796. checkMatrix(matrix)
  1797. let result
  1798. if (showExtras)
  1799. result = libmupdf._wasm_new_pixmap_from_page(this.pointer,
  1800. MATRIX(matrix),
  1801. colorspace.pointer,
  1802. alpha)
  1803. else
  1804. result = libmupdf._wasm_new_pixmap_from_page_contents(this.pointer,
  1805. MATRIX(matrix),
  1806. colorspace.pointer,
  1807. alpha)
  1808. return new Pixmap(result)
  1809. }
  1810. toDisplayList(showExtras = true) {
  1811. let result
  1812. if (showExtras)
  1813. result = libmupdf._wasm_new_display_list_from_page(this.pointer)
  1814. else
  1815. result = libmupdf._wasm_new_display_list_from_page_contents(this.pointer)
  1816. return new DisplayList(result)
  1817. }
  1818. toStructuredText(options = "") {
  1819. checkType(options, "string")
  1820. return new StructuredText(libmupdf._wasm_new_stext_page_from_page(this.pointer, STRING(options)))
  1821. }
  1822. getLinks() {
  1823. let links: Link[] = []
  1824. let link = libmupdf._wasm_load_links(this.pointer)
  1825. while (link) {
  1826. links.push(new Link(libmupdf._wasm_keep_link(link)))
  1827. link = libmupdf._wasm_link_get_next(link)
  1828. }
  1829. return links
  1830. }
  1831. createLink(bbox: Rect, uri: string) {
  1832. checkRect(bbox)
  1833. return new Link(libmupdf._wasm_create_link(this.pointer, RECT(bbox), STRING(uri)))
  1834. }
  1835. deleteLink(link: Link) {
  1836. checkType(link, Link)
  1837. libmupdf._wasm_delete_link(this.pointer, link.pointer)
  1838. }
  1839. search(needle: string, max_hits = 500) {
  1840. return runSearch(libmupdf._wasm_search_page, this.pointer, needle, max_hits)
  1841. }
  1842. }
  1843. /* -------------------------------------------------------------------------- */
  1844. export class PDFDocument extends Document {
  1845. // Create a new empty document
  1846. constructor()
  1847. // Open an existing document
  1848. constructor(filename: string)
  1849. constructor(data: Buffer | ArrayBuffer | Uint8Array | Stream)
  1850. // PRIVATE
  1851. constructor(clone: PDFDocument)
  1852. constructor(pointer: Pointer<"any_document">)
  1853. constructor(data: Buffer | ArrayBuffer | Uint8Array | Stream)
  1854. constructor(arg1?: Pointer<"any_document"> | Buffer | ArrayBuffer | Uint8Array | Stream | PDFDocument | string) {
  1855. if (typeof arg1 === "undefined")
  1856. super(libmupdf._wasm_pdf_create_document())
  1857. else if (typeof arg1 === "number")
  1858. super(arg1)
  1859. else if (arg1 instanceof PDFDocument) {
  1860. super(arg1.pointer)
  1861. libmupdf._wasm_keep_document(this.pointer)
  1862. } else {
  1863. let doc = Document.openDocument(arg1, "application/pdf")
  1864. if (doc instanceof PDFDocument)
  1865. return doc
  1866. throw new Error("not a PDF document")
  1867. }
  1868. }
  1869. override loadPage(index: number) {
  1870. return super.loadPage(index) as PDFPage
  1871. }
  1872. // PDFObject instances are always bound to a document, so the WASM/JS value interface lives here.
  1873. // Wrap a pdf_obj in a Userdata object. The pointer must be newly created or we already own it.
  1874. _fromPDFObjectNew(ptr: Pointer<"pdf_obj">) {
  1875. if (ptr === 0)
  1876. return PDFObject.Null
  1877. return new PDFObject(this, ptr)
  1878. }
  1879. // Wrap a pdf_obj in a Userdata object. The pointer must be a borrowed pointer, so we have to take ownership.
  1880. _fromPDFObjectKeep(ptr: Pointer<"pdf_obj">) {
  1881. if (ptr === 0)
  1882. return PDFObject.Null
  1883. return new PDFObject(this, libmupdf._wasm_pdf_keep_obj(ptr))
  1884. }
  1885. _toPDFObject(obj: any) {
  1886. if (obj instanceof PDFObject)
  1887. return obj
  1888. if (obj === null || obj === undefined)
  1889. return this.newNull()
  1890. if (typeof obj === "string") {
  1891. // if a JS string is surrounded by parens, convert it to a PDF string
  1892. if (obj.startsWith("(") && obj.endsWith(")"))
  1893. return this.newString(obj.slice(1, -1))
  1894. // otherwise treat it as a name
  1895. return this.newName(obj)
  1896. }
  1897. if (typeof obj === "number") {
  1898. if (obj === (obj | 0))
  1899. return this.newInteger(obj)
  1900. return this.newReal(obj)
  1901. }
  1902. if (typeof obj === "boolean")
  1903. return this.newBoolean(obj)
  1904. if (obj instanceof Array) {
  1905. let result = this.newArray(obj.length)
  1906. for (let item of obj)
  1907. result.push(item)
  1908. return result
  1909. }
  1910. if (obj instanceof Object) {
  1911. let result = this.newDictionary()
  1912. for (let key in obj)
  1913. result.put(key, obj[key])
  1914. return result
  1915. }
  1916. throw new TypeError("cannot convert value to PDFObject")
  1917. }
  1918. _PDFOBJ(obj: any) {
  1919. // Note: We have to create a PDFObject instance for garbage collection.
  1920. return this._toPDFObject(obj).pointer
  1921. }
  1922. getVersion() {
  1923. return libmupdf._wasm_pdf_version(this.pointer)
  1924. }
  1925. getLanguage() {
  1926. return fromString(libmupdf._wasm_pdf_document_language(this.pointer))
  1927. }
  1928. setLanguage(lang: string) {
  1929. libmupdf._wasm_pdf_set_document_language(this.pointer, STRING(lang))
  1930. }
  1931. countObjects() {
  1932. return libmupdf._wasm_pdf_xref_len(this.pointer)
  1933. }
  1934. getTrailer() {
  1935. return new PDFObject(this, libmupdf._wasm_pdf_trailer(this.pointer))
  1936. }
  1937. createObject() {
  1938. let num = libmupdf._wasm_pdf_create_object(this.pointer)
  1939. return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_indirect(this.pointer, num))
  1940. }
  1941. newNull() { return PDFObject.Null }
  1942. newBoolean(v: boolean) { return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_bool(v)) }
  1943. newInteger(v: number) { return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_int(v)) }
  1944. newReal(v: number) { return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_real(v)) }
  1945. newName(v: string) { return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_name(STRING(v))) }
  1946. newString(v: string) { return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_text_string(STRING(v))) }
  1947. newByteString(v: Uint8Array) {
  1948. checkType(v, Uint8Array)
  1949. let len = v.byteLength
  1950. let ptr = Malloc<"char">(len)
  1951. libmupdf.HEAPU8.set(v, ptr)
  1952. try {
  1953. return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_string(ptr, len))
  1954. } finally {
  1955. Free(ptr)
  1956. }
  1957. }
  1958. newIndirect(v: number) { return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_indirect(this.pointer, v)) }
  1959. newArray(cap=8) { return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_array(this.pointer, cap)) }
  1960. newDictionary(cap=8) { return this._fromPDFObjectNew(libmupdf._wasm_pdf_new_dict(this.pointer, cap)) }
  1961. deleteObject(num: number | PDFObject) {
  1962. if (num instanceof PDFObject)
  1963. num = num.asIndirect()
  1964. else
  1965. checkType(num, "number")
  1966. libmupdf._wasm_pdf_delete_object(this.pointer, num)
  1967. }
  1968. addObject(obj: any) {
  1969. return this._fromPDFObjectNew(libmupdf._wasm_pdf_add_object(this.pointer, this._PDFOBJ(obj)))
  1970. }
  1971. addStream(buf: AnyBuffer, obj: any) {
  1972. return this._fromPDFObjectNew(libmupdf._wasm_pdf_add_stream(this.pointer, BUFFER(buf), this._PDFOBJ(obj), 0))
  1973. }
  1974. addRawStream(buf: AnyBuffer, obj: any) {
  1975. return this._fromPDFObjectNew(libmupdf._wasm_pdf_add_stream(this.pointer, BUFFER(buf), this._PDFOBJ(obj), 1))
  1976. }
  1977. newGraftMap() {
  1978. return new PDFGraftMap(this, libmupdf._wasm_pdf_new_graft_map(this.pointer))
  1979. }
  1980. graftObject(obj: PDFObject) {
  1981. checkType(obj, PDFObject)
  1982. return this._fromPDFObjectNew(libmupdf._wasm_pdf_graft_object(this.pointer, obj.pointer))
  1983. }
  1984. graftPage(to: number, srcDoc: PDFDocument, srcPage: number) {
  1985. checkType(to, "number")
  1986. checkType(srcDoc, PDFDocument)
  1987. checkType(srcPage, "number")
  1988. libmupdf._wasm_pdf_graft_page(this.pointer, to, srcDoc.pointer, srcPage)
  1989. }
  1990. addSimpleFont(font: Font, encoding: FontSimpleEncoding = "Latin") {
  1991. checkType(font, Font)
  1992. var encoding_ix = ENUM<FontSimpleEncoding>(encoding, Font.SIMPLE_ENCODING)
  1993. return this._fromPDFObjectNew(libmupdf._wasm_pdf_add_simple_font(this.pointer, font.pointer, encoding_ix))
  1994. }
  1995. addCJKFont(font: Font, lang: FontCJKOrdering | FontCJKLanguage, wmode = 0, serif = true) {
  1996. checkType(font, Font)
  1997. if (typeof lang === "string")
  1998. lang = Font.CJK_ORDERING_BY_LANG[lang]
  1999. return this._fromPDFObjectNew(libmupdf._wasm_pdf_add_cjk_font(this.pointer, font.pointer, lang, wmode, serif))
  2000. }
  2001. addFont(font: Font) {
  2002. checkType(font, Font)
  2003. return this._fromPDFObjectNew(libmupdf._wasm_pdf_add_cid_font(this.pointer, font.pointer))
  2004. }
  2005. addImage(image: Image) {
  2006. checkType(image, Image)
  2007. return this._fromPDFObjectNew(libmupdf._wasm_pdf_add_image(this.pointer, image.pointer))
  2008. }
  2009. loadImage(ref: PDFObject) {
  2010. checkType(ref, PDFObject)
  2011. return new Image(libmupdf._wasm_pdf_load_image(this.pointer, ref.pointer))
  2012. }
  2013. findPage(index: number) {
  2014. checkType(index, "number")
  2015. return this._fromPDFObjectKeep(libmupdf._wasm_pdf_lookup_page_obj(this.pointer, index))
  2016. }
  2017. addPage(mediabox: Rect, rotate: Rotate, resources: any, contents: AnyBuffer) {
  2018. checkRect(mediabox)
  2019. checkType(rotate, "number")
  2020. return this._fromPDFObjectNew(
  2021. libmupdf._wasm_pdf_add_page(
  2022. this.pointer,
  2023. RECT(mediabox),
  2024. rotate,
  2025. this._PDFOBJ(resources),
  2026. BUFFER(contents)
  2027. )
  2028. )
  2029. }
  2030. insertPage(at: number, obj: PDFObject) {
  2031. checkType(at, "number")
  2032. libmupdf._wasm_pdf_insert_page(this.pointer, at, this._PDFOBJ(obj))
  2033. }
  2034. deletePage(at: number) {
  2035. checkType(at, "number")
  2036. libmupdf._wasm_pdf_delete_page(this.pointer, at)
  2037. }
  2038. isEmbeddedFile(ref: PDFObject) {
  2039. checkType(ref, PDFObject)
  2040. return libmupdf._wasm_pdf_is_embedded_file(ref.pointer)
  2041. }
  2042. addEmbeddedFile(filename: string, mimetype: string, contents: AnyBuffer, created: Date, modified: Date, checksum = false) {
  2043. checkType(filename, "string")
  2044. checkType(mimetype, "string")
  2045. checkType(created, Date)
  2046. checkType(modified, Date)
  2047. checkType(checksum, "boolean")
  2048. return this._fromPDFObjectNew(
  2049. libmupdf._wasm_pdf_add_embedded_file(
  2050. this.pointer,
  2051. STRING(filename),
  2052. STRING2(mimetype),
  2053. BUFFER(contents),
  2054. created.getTime() / 1000 | 0,
  2055. modified.getTime() / 1000 | 0,
  2056. checksum
  2057. )
  2058. )
  2059. }
  2060. getEmbeddedFileParams(ref: PDFObject) {
  2061. checkType(ref, PDFObject)
  2062. let ptr = libmupdf._wasm_pdf_get_embedded_file_params(ref.pointer)
  2063. return {
  2064. filename:
  2065. fromString(libmupdf._wasm_pdf_embedded_file_params_get_filename(ptr)),
  2066. mimetype:
  2067. fromString(libmupdf._wasm_pdf_embedded_file_params_get_mimetype(ptr)),
  2068. size:
  2069. libmupdf._wasm_pdf_embedded_file_params_get_filename(ptr),
  2070. creationDate:
  2071. new Date(libmupdf._wasm_pdf_embedded_file_params_get_created(ptr) * 1000),
  2072. modificationDate:
  2073. new Date(libmupdf._wasm_pdf_embedded_file_params_get_modified(ptr) * 1000),
  2074. }
  2075. }
  2076. getEmbeddedFileContents(ref: PDFObject) {
  2077. checkType(ref, PDFObject)
  2078. let contents = libmupdf._wasm_pdf_load_embedded_file_contents(ref.pointer)
  2079. if (contents)
  2080. return new Buffer(contents)
  2081. return null
  2082. }
  2083. getEmbeddedFiles(): Record<string,PDFObject> {
  2084. function _getEmbeddedFilesRec(result: Record<string,PDFObject>, N: PDFObject) {
  2085. var i, n
  2086. if (N.isDictionary()) {
  2087. var NN = N.get("Names")
  2088. if (NN)
  2089. for (i = 0, n = NN.length; i < n; i += 2)
  2090. result[NN.get(i+0).asString()] = NN.get(i+1)
  2091. var NK = N.get("Kids")
  2092. if (NK)
  2093. for (i = 0, n = NK.length; i < n; i += 1)
  2094. _getEmbeddedFilesRec(result, NK.get(i))
  2095. }
  2096. return result
  2097. }
  2098. return _getEmbeddedFilesRec({}, this.getTrailer().get("Root", "Names", "EmbeddedFiles"))
  2099. }
  2100. loadNameTree(treeName: string): Record<string,PDFObject> {
  2101. function _loadNameTreeRec(dict: Record<string,PDFObject>, node: PDFObject) {
  2102. var kids = node.get("Kids")
  2103. if (kids && kids.isArray())
  2104. for (var i = 0; i < kids.length; i += 1)
  2105. _loadNameTreeRec(dict, kids.get(i))
  2106. var names = node.get("Names")
  2107. if (names && names.isArray())
  2108. for (var i = 0; i < names.length; i += 2)
  2109. dict[names.get(i).asString()] = names.get(i+1)
  2110. }
  2111. var node = this.getTrailer().get("Root").get("Names").get(treeName)
  2112. var dict = {}
  2113. if (node.isDictionary())
  2114. _loadNameTreeRec(dict, node)
  2115. return dict
  2116. }
  2117. insertEmbeddedFile(filename: string, filespec: PDFObject) {
  2118. var efs = this.getEmbeddedFiles()
  2119. efs[filename] = filespec
  2120. this._rewriteEmbeddedFiles(efs)
  2121. }
  2122. deleteEmbeddedFile(filename: string) {
  2123. var efs = this.getEmbeddedFiles()
  2124. delete efs[filename]
  2125. this._rewriteEmbeddedFiles(efs)
  2126. }
  2127. _rewriteEmbeddedFiles(efs: Record<string,PDFObject>) {
  2128. var efs_keys = Object.keys(efs)
  2129. efs_keys.sort()
  2130. var root = this.getTrailer().get("Root")
  2131. var root_names = root.get("Names")
  2132. if (!root_names.isDictionary())
  2133. root_names = root.put("Names", this.newDictionary(1))
  2134. var root_names_efs = root_names.put("EmbeddedFiles", this.newDictionary(1))
  2135. var root_names_efs_names = root_names_efs.put("Names", this.newArray(efs_keys.length * 2))
  2136. for (var key of efs_keys) {
  2137. root_names_efs_names.push(this.newString(key))
  2138. root_names_efs_names.push(efs[key])
  2139. }
  2140. }
  2141. saveToBuffer(options: string | Record<string,any> = "") {
  2142. var options_string
  2143. if (typeof options === "object") {
  2144. options_string = Object.entries(options).map(kv => {
  2145. var k: string = kv[0]
  2146. var v: any = kv[1]
  2147. if (v === true)
  2148. return k + "=" + "yes"
  2149. else if (v === false)
  2150. return k + "=" + "no"
  2151. else
  2152. return k + "=" + String(v).replaceAll(",", ":")
  2153. }).join(",")
  2154. } else {
  2155. options_string = options
  2156. }
  2157. return new Buffer(libmupdf._wasm_pdf_write_document_buffer(this.pointer, STRING(options_string)))
  2158. }
  2159. save(filename: string, options: string | Record<string,any> = "") {
  2160. if (node_fs)
  2161. node_fs.writeFileSync(filename, this.saveToBuffer(options).asUint8Array())
  2162. else
  2163. throw new Error("missing 'fs' module")
  2164. }
  2165. static readonly PAGE_LABEL_NONE = "\0"
  2166. static readonly PAGE_LABEL_DECIMAL = "D"
  2167. static readonly PAGE_LABEL_ROMAN_UC = "R"
  2168. static readonly PAGE_LABEL_ROMAN_LC = "r"
  2169. static readonly PAGE_LABEL_ALPHA_UC = "A"
  2170. static readonly PAGE_LABEL_ALPHA_LC = "a"
  2171. setPageLabels(index: number, style = "D", prefix = "", start = 1) {
  2172. libmupdf._wasm_pdf_set_page_labels(this.pointer, index, style.charCodeAt(0), STRING(prefix), start)
  2173. }
  2174. deletePageLabels(index: number) {
  2175. libmupdf._wasm_pdf_delete_page_labels(this.pointer, index)
  2176. }
  2177. wasRepaired() {
  2178. return !!libmupdf._wasm_pdf_was_repaired(this.pointer)
  2179. }
  2180. hasUnsavedChanges() {
  2181. return !!libmupdf._wasm_pdf_has_unsaved_changes(this.pointer)
  2182. }
  2183. countVersions() {
  2184. return libmupdf._wasm_pdf_count_versions(this.pointer)
  2185. }
  2186. countUnsavedVersions() {
  2187. return libmupdf._wasm_pdf_count_unsaved_versions(this.pointer)
  2188. }
  2189. validateChangeHistory() {
  2190. return libmupdf._wasm_pdf_validate_change_history(this.pointer)
  2191. }
  2192. canBeSavedIncrementally() {
  2193. return !!libmupdf._wasm_pdf_can_be_saved_incrementally(this.pointer)
  2194. }
  2195. enableJournal() {
  2196. libmupdf._wasm_pdf_enable_journal(this.pointer)
  2197. }
  2198. getJournal() {
  2199. let position = libmupdf._wasm_pdf_undoredo_state_position(this.pointer)
  2200. let n = libmupdf._wasm_pdf_undoredo_state_count(this.pointer)
  2201. let steps: string[] = []
  2202. for (let i = 0; i < n; ++i)
  2203. steps.push(
  2204. fromString(
  2205. libmupdf._wasm_pdf_undoredo_step(this.pointer, i),
  2206. )
  2207. )
  2208. return { position, steps }
  2209. }
  2210. beginOperation(op: string) {
  2211. libmupdf._wasm_pdf_begin_operation(this.pointer, STRING(op))
  2212. }
  2213. beginImplicitOperation() {
  2214. libmupdf._wasm_pdf_begin_implicit_operation(this.pointer)
  2215. }
  2216. endOperation() {
  2217. libmupdf._wasm_pdf_end_operation(this.pointer)
  2218. }
  2219. abandonOperation() {
  2220. libmupdf._wasm_pdf_abandon_operation(this.pointer)
  2221. }
  2222. canUndo() {
  2223. return !!libmupdf._wasm_pdf_can_undo(this.pointer)
  2224. }
  2225. canRedo() {
  2226. return !!libmupdf._wasm_pdf_can_redo(this.pointer)
  2227. }
  2228. undo() {
  2229. libmupdf._wasm_pdf_undo(this.pointer)
  2230. }
  2231. redo() {
  2232. libmupdf._wasm_pdf_redo(this.pointer)
  2233. }
  2234. isJSSupported() {
  2235. return !!libmupdf._wasm_pdf_js_supported(this.pointer)
  2236. }
  2237. enableJS() {
  2238. libmupdf._wasm_pdf_enable_js(this.pointer)
  2239. }
  2240. disableJS() {
  2241. libmupdf._wasm_pdf_disable_js(this.pointer)
  2242. }
  2243. setJSEventListener(_listener: any) {
  2244. throw "TODO"
  2245. }
  2246. rearrangePages(pages: number[]) {
  2247. let n = pages.length
  2248. let ptr = Malloc<"int">(n << 2)
  2249. for (let i = 0; i < n; ++i)
  2250. libmupdf.HEAPU32[(ptr >> 2) + i] = pages[i] || 0
  2251. try {
  2252. libmupdf._wasm_pdf_rearrange_pages(this.pointer, n, ptr)
  2253. } finally {
  2254. Free(ptr)
  2255. }
  2256. }
  2257. subsetFonts() {
  2258. libmupdf._wasm_pdf_subset_fonts(this.pointer)
  2259. }
  2260. bake(bakeAnnots = true, bakeWidgets = true) {
  2261. libmupdf._wasm_pdf_bake_document(this.pointer, bakeAnnots, bakeWidgets)
  2262. }
  2263. countLayers(): number {
  2264. return libmupdf._wasm_pdf_count_layers(this.pointer)
  2265. }
  2266. isLayerVisible(layer: number): boolean {
  2267. return !!libmupdf._wasm_pdf_layer_is_enabled(this.pointer, layer)
  2268. }
  2269. setLayerVisible(layer: number, visible: boolean): void {
  2270. libmupdf._wasm_pdf_enable_layer(this.pointer, layer, Number(visible))
  2271. }
  2272. getLayerName(layer: number): string {
  2273. return fromString(libmupdf._wasm_pdf_layer_name(this.pointer, layer))
  2274. }
  2275. resetForm(fields: PDFObject, exclude: boolean) {
  2276. libmupdf._wasm_pdf_reset_form(this.pointer, this._PDFOBJ(fields), Number(exclude))
  2277. }
  2278. }
  2279. export class PDFPage extends Page {
  2280. _doc: PDFDocument
  2281. _annots: PDFAnnotation[] | null
  2282. _widgets: PDFWidget[] | null
  2283. // PRIVATE
  2284. constructor(doc: PDFDocument, pointer: Pointer<"any_page">) {
  2285. super(pointer)
  2286. this._doc = doc
  2287. this._annots = null
  2288. this._widgets = null
  2289. }
  2290. getObject() {
  2291. return this._doc._fromPDFObjectKeep(libmupdf._wasm_pdf_page_get_obj(this.pointer))
  2292. }
  2293. getTransform() {
  2294. return fromMatrix(libmupdf._wasm_pdf_page_transform(this.pointer))
  2295. }
  2296. setPageBox(box: PageBox, rect: Rect) {
  2297. let box_ix = ENUM<PageBox>(box, Page.BOXES)
  2298. checkRect(rect)
  2299. libmupdf._wasm_pdf_set_page_box(this.pointer, box_ix, RECT(rect))
  2300. }
  2301. override toPixmap(matrix: Matrix, colorspace: ColorSpace, alpha = false, showExtras = true, usage = "View", box: PageBox = "CropBox") {
  2302. checkMatrix(matrix)
  2303. checkType(colorspace, ColorSpace)
  2304. let box_ix = ENUM<PageBox>(box, Page.BOXES)
  2305. let result
  2306. if (showExtras)
  2307. result = libmupdf._wasm_pdf_new_pixmap_from_page_with_usage(this.pointer,
  2308. MATRIX(matrix),
  2309. colorspace.pointer,
  2310. alpha,
  2311. STRING(usage),
  2312. box_ix)
  2313. else
  2314. result = libmupdf._wasm_pdf_new_pixmap_from_page_contents_with_usage(this.pointer,
  2315. MATRIX(matrix),
  2316. colorspace.pointer,
  2317. alpha,
  2318. STRING(usage),
  2319. box_ix)
  2320. return new Pixmap(result)
  2321. }
  2322. getWidgets() {
  2323. if (!this._widgets) {
  2324. this._widgets = []
  2325. let widget = libmupdf._wasm_pdf_first_widget(this.pointer)
  2326. while (widget) {
  2327. this._widgets.push(new PDFWidget(this._doc, libmupdf._wasm_pdf_keep_annot(widget)))
  2328. widget = libmupdf._wasm_pdf_next_widget(widget)
  2329. }
  2330. }
  2331. return this._widgets
  2332. }
  2333. getAnnotations() {
  2334. if (!this._annots) {
  2335. this._annots = []
  2336. let annot = libmupdf._wasm_pdf_first_annot(this.pointer)
  2337. while (annot) {
  2338. this._annots.push(new PDFAnnotation(this._doc, libmupdf._wasm_pdf_keep_annot(annot)))
  2339. annot = libmupdf._wasm_pdf_next_annot(annot)
  2340. }
  2341. }
  2342. return this._annots
  2343. }
  2344. createAnnotation(type: PDFAnnotationType) {
  2345. let type_ix = ENUM<PDFAnnotationType>(type, PDFAnnotation.ANNOT_TYPES)
  2346. let annot = new PDFAnnotation(this._doc, libmupdf._wasm_pdf_create_annot(this.pointer, type_ix))
  2347. if (this._annots)
  2348. this._annots.push(annot)
  2349. return annot
  2350. }
  2351. deleteAnnotation(annot: PDFAnnotation) {
  2352. checkType(annot, PDFAnnotation)
  2353. libmupdf._wasm_pdf_delete_annot(this.pointer, annot.pointer)
  2354. if (this._annots) {
  2355. let ix = this._annots.indexOf(annot)
  2356. if (ix >= 0)
  2357. this._annots.splice(ix, 1)
  2358. }
  2359. }
  2360. static readonly REDACT_IMAGE_NONE = 0
  2361. static readonly REDACT_IMAGE_REMOVE = 1
  2362. static readonly REDACT_IMAGE_PIXELS = 2
  2363. static readonly REDACT_IMAGE_UNLESS_INVISIBLE = 3
  2364. static readonly REDACT_LINE_ART_NONE = 0
  2365. static readonly REDACT_LINE_ART_REMOVE_IF_COVERED = 1
  2366. static readonly REDACT_LINE_ART_REMOVE_IF_TOUCHED = 2
  2367. static readonly REDACT_TEXT_REMOVE = 0
  2368. static readonly REDACT_TEXT_NONE = 1
  2369. applyRedactions(black_boxes = true, image_method = 2, line_art_method = 1, text_method = 0) {
  2370. libmupdf._wasm_pdf_redact_page(this.pointer, Number(black_boxes), image_method, line_art_method, text_method)
  2371. }
  2372. update() {
  2373. return !!libmupdf._wasm_pdf_update_page(this.pointer)
  2374. }
  2375. }
  2376. type PDFObjectPath = Array<number | string | PDFObject>
  2377. export class PDFObject extends Userdata<"pdf_obj"> {
  2378. static override readonly _drop = libmupdf._wasm_pdf_drop_obj
  2379. static readonly Null = new PDFObject(null as unknown as PDFDocument, 0 as Pointer<"pdf_obj">)
  2380. _doc: PDFDocument
  2381. // PRIVATE
  2382. constructor(doc: PDFDocument, pointer: Pointer<"pdf_obj">) {
  2383. super(libmupdf._wasm_pdf_keep_obj(pointer))
  2384. this._doc = doc
  2385. }
  2386. isNull() { return this === PDFObject.Null }
  2387. isIndirect() { return !!libmupdf._wasm_pdf_is_indirect(this.pointer) }
  2388. isBoolean() { return !!libmupdf._wasm_pdf_is_bool(this.pointer) }
  2389. isInteger() { return !!libmupdf._wasm_pdf_is_int(this.pointer) }
  2390. isNumber() { return !!libmupdf._wasm_pdf_is_number(this.pointer) }
  2391. isName() { return !!libmupdf._wasm_pdf_is_name(this.pointer) }
  2392. isString() { return !!libmupdf._wasm_pdf_is_string(this.pointer) }
  2393. isArray() { return !!libmupdf._wasm_pdf_is_array(this.pointer) }
  2394. isDictionary() { return !!libmupdf._wasm_pdf_is_dict(this.pointer) }
  2395. isStream() { return !!libmupdf._wasm_pdf_is_stream(this.pointer) }
  2396. asIndirect(): number { return libmupdf._wasm_pdf_to_num(this.pointer) }
  2397. asBoolean() { return !!libmupdf._wasm_pdf_to_bool(this.pointer) }
  2398. asNumber(): number { return libmupdf._wasm_pdf_to_real(this.pointer) }
  2399. asName() { return fromString(libmupdf._wasm_pdf_to_name(this.pointer)) }
  2400. asString() { return fromString(libmupdf._wasm_pdf_to_text_string(this.pointer)) }
  2401. asByteString() {
  2402. let ptr = libmupdf._wasm_pdf_to_string(this.pointer, _wasm_int)
  2403. let len = libmupdf.HEAPU32[_wasm_int >> 2] as number
  2404. return libmupdf.HEAPU8.slice(ptr, ptr + len)
  2405. }
  2406. readStream() { return new Buffer(libmupdf._wasm_pdf_load_stream(this.pointer)) }
  2407. readRawStream() { return new Buffer(libmupdf._wasm_pdf_load_raw_stream(this.pointer)) }
  2408. writeObject(obj: any) {
  2409. if (!this.isIndirect())
  2410. throw new TypeError("can only call PDFObject.writeObject on an indirect reference")
  2411. libmupdf._wasm_pdf_update_object(this._doc.pointer, this.asIndirect(), this._doc._PDFOBJ(obj))
  2412. }
  2413. writeStream(buf: AnyBuffer) {
  2414. if (!this.isIndirect())
  2415. throw new TypeError("can only call PDFObject.writeStream on an indirect reference")
  2416. libmupdf._wasm_pdf_update_stream(this._doc.pointer, this.pointer, BUFFER(buf), 0)
  2417. }
  2418. writeRawStream(buf: AnyBuffer) {
  2419. if (!this.isIndirect())
  2420. throw new TypeError("can only call PDFObject.writeRawStream on an indirect reference")
  2421. libmupdf._wasm_pdf_update_stream(this._doc.pointer, this.pointer, BUFFER(buf), 1)
  2422. }
  2423. resolve() {
  2424. return this._doc._fromPDFObjectKeep(libmupdf._wasm_pdf_resolve_indirect(this.pointer))
  2425. }
  2426. get length() {
  2427. return libmupdf._wasm_pdf_array_len(this.pointer)
  2428. }
  2429. _get(path: PDFObjectPath) {
  2430. let obj = this.pointer
  2431. for (let key of path) {
  2432. if (typeof key === "number")
  2433. obj = libmupdf._wasm_pdf_array_get(obj, key)
  2434. else if (key instanceof PDFObject)
  2435. obj = libmupdf._wasm_pdf_dict_get(obj, key.pointer)
  2436. else
  2437. obj = libmupdf._wasm_pdf_dict_gets(obj, STRING(key))
  2438. if (obj === 0)
  2439. break
  2440. }
  2441. return obj
  2442. }
  2443. get(...path: PDFObjectPath): PDFObject { return this._doc._fromPDFObjectKeep(this._get(path)) }
  2444. getIndirect(...path: PDFObjectPath): number { return libmupdf._wasm_pdf_to_num(this._get(path)) }
  2445. getBoolean(...path: PDFObjectPath): boolean { return !!libmupdf._wasm_pdf_to_bool(this._get(path)) }
  2446. getNumber(...path: PDFObjectPath): number { return libmupdf._wasm_pdf_to_real(this._get(path)) }
  2447. getName(...path: PDFObjectPath): string { return fromString(libmupdf._wasm_pdf_to_name(this._get(path))) }
  2448. getString(...path: PDFObjectPath): string { return fromString(libmupdf._wasm_pdf_to_text_string(this._get(path))) }
  2449. getInheritable(key: string | PDFObject) {
  2450. if (key instanceof PDFObject)
  2451. return this._doc._fromPDFObjectKeep(libmupdf._wasm_pdf_dict_get_inheritable(this.pointer, key.pointer))
  2452. return this._doc._fromPDFObjectKeep(libmupdf._wasm_pdf_dict_gets_inheritable(this.pointer, STRING(key)))
  2453. }
  2454. put(key: number | string | PDFObject, value: any) {
  2455. value = this._doc._toPDFObject(value)
  2456. if (typeof key === "number")
  2457. libmupdf._wasm_pdf_array_put(this.pointer, key, value.pointer)
  2458. else if (key instanceof PDFObject)
  2459. libmupdf._wasm_pdf_dict_put(this.pointer, key.pointer, value.pointer)
  2460. else
  2461. libmupdf._wasm_pdf_dict_puts(this.pointer, STRING(key), value.pointer)
  2462. return value
  2463. }
  2464. push(value: any) {
  2465. value = this._doc._toPDFObject(value)
  2466. libmupdf._wasm_pdf_array_push(this.pointer, value.pointer)
  2467. return value
  2468. }
  2469. delete(key: number | string | PDFObject) {
  2470. if (typeof key === "number")
  2471. libmupdf._wasm_pdf_array_delete(this.pointer, key)
  2472. else if (key instanceof PDFObject)
  2473. libmupdf._wasm_pdf_dict_del(this.pointer, key.pointer)
  2474. else
  2475. libmupdf._wasm_pdf_dict_dels(this.pointer, STRING(key))
  2476. }
  2477. override valueOf() {
  2478. if (this.isNull()) return null
  2479. if (this.isBoolean()) return this.asBoolean()
  2480. if (this.isNumber()) return this.asNumber()
  2481. if (this.isName()) return this.asName()
  2482. if (this.isString()) return this.asString()
  2483. if (this.isIndirect()) return `${this.asIndirect()} 0 R`
  2484. return this
  2485. }
  2486. override toString(tight = true, ascii = true) {
  2487. return fromStringFree(libmupdf._wasm_pdf_sprint_obj(this.pointer, tight, ascii))
  2488. }
  2489. forEach(fn: (val: PDFObject, key: number | string, self: PDFObject) => void) {
  2490. if (this.isArray()) {
  2491. let n = this.length
  2492. for (let i = 0; i < n; ++i)
  2493. fn(this.get(i), i, this)
  2494. } else if (this.isDictionary()) {
  2495. let n = libmupdf._wasm_pdf_dict_len(this.pointer)
  2496. for (let i = 0; i < n; ++i) {
  2497. let key = this._doc._fromPDFObjectKeep(libmupdf._wasm_pdf_dict_get_key(this.pointer, i))
  2498. let val = this._doc._fromPDFObjectKeep(libmupdf._wasm_pdf_dict_get_val(this.pointer, i))
  2499. fn(val, key.asName(), this)
  2500. }
  2501. }
  2502. }
  2503. // Convert to plain Javascript values, objects, and arrays.
  2504. // If you want to resolve indirect references, pass an empty object or array as the first argument.
  2505. // On exit, this object will contain all indirect objects encountered indexed by object number.
  2506. // Note: This function will omit cyclic references.
  2507. asJS(seen?: Record<number,PDFObject>): any {
  2508. if (this.isIndirect()) {
  2509. let ref = this.asIndirect()
  2510. if (!seen)
  2511. return `${ref} 0 R`
  2512. if (ref in seen)
  2513. return seen[ref]
  2514. seen[ref] = PDFObject.Null // stop recursion!
  2515. return seen[ref] = this.resolve().asJS(seen)
  2516. }
  2517. if (this.isArray()) {
  2518. let result: any[] = []
  2519. this.forEach(val => {
  2520. result.push(val.asJS(seen))
  2521. })
  2522. return result
  2523. }
  2524. if (this.isDictionary()) {
  2525. let result: Record<string,any> = {}
  2526. this.forEach((val, key) => {
  2527. result[key] = val.asJS(seen)
  2528. })
  2529. return result
  2530. }
  2531. return this.valueOf()
  2532. }
  2533. }
  2534. export class PDFGraftMap extends Userdata<"pdf_graft_map"> {
  2535. static override readonly _drop = libmupdf._wasm_pdf_drop_graft_map
  2536. _doc: PDFDocument
  2537. // PRIVATE
  2538. constructor(doc: PDFDocument, pointer: Pointer<"pdf_graft_map">) {
  2539. super(pointer)
  2540. this._doc = doc
  2541. }
  2542. graftObject(obj: PDFObject) {
  2543. checkType(obj, PDFObject)
  2544. return this._doc._fromPDFObjectNew(libmupdf._wasm_pdf_graft_mapped_object(this.pointer, obj.pointer))
  2545. }
  2546. graftPage(to: number, srcDoc: PDFDocument, srcPage: number) {
  2547. checkType(to, "number")
  2548. checkType(srcDoc, PDFDocument)
  2549. checkType(srcPage, "number")
  2550. libmupdf._wasm_pdf_graft_mapped_page(this.pointer, to, srcDoc.pointer, srcPage)
  2551. }
  2552. }
  2553. export type PDFAnnotationType =
  2554. "Text" |
  2555. "Link" |
  2556. "FreeText" |
  2557. "Line" |
  2558. "Square" |
  2559. "Circle" |
  2560. "Polygon" |
  2561. "PolyLine" |
  2562. "Highlight" |
  2563. "Underline" |
  2564. "Squiggly" |
  2565. "StrikeOut" |
  2566. "Redact" |
  2567. "Stamp" |
  2568. "Caret" |
  2569. "Ink" |
  2570. "Popup" |
  2571. "FileAttachment" |
  2572. "Sound" |
  2573. "Movie" |
  2574. "RichMedia" |
  2575. "Widget" |
  2576. "Screen" |
  2577. "PrinterMark" |
  2578. "TrapNet" |
  2579. "Watermark" |
  2580. "3D" |
  2581. "Projection"
  2582. export type PDFAnnotationLineEndingStyle =
  2583. "None" |
  2584. "Square" |
  2585. "Circle" |
  2586. "Diamond" |
  2587. "OpenArrow" |
  2588. "ClosedArrow" |
  2589. "Butt" |
  2590. "ROpenArrow" |
  2591. "RClosedArrow" |
  2592. "Slash"
  2593. export type PDFAnnotationBorderStyle = "Solid" | "Dashed" | "Beveled" | "Inset" | "Underline"
  2594. export type PDFAnnotationBorderEffect = "None" | "Cloudy"
  2595. export type PDFAnnotationIntent =
  2596. null |
  2597. "FreeTextCallout" |
  2598. "FreeTextTypeWriter" |
  2599. "LineArrow" |
  2600. "LineDimension" |
  2601. "PloyLine" |
  2602. "PolygonCloud" |
  2603. "PolygonDimension" |
  2604. "StampImage" |
  2605. "StampSnapshot"
  2606. export class PDFAnnotation extends Userdata<"pdf_annot"> {
  2607. static override readonly _drop = libmupdf._wasm_pdf_drop_annot
  2608. _doc: PDFDocument
  2609. /* IMPORTANT: Keep in sync with mupdf/pdf/annot.h and PDFAnnotation.java */
  2610. static readonly ANNOT_TYPES: PDFAnnotationType[] = [
  2611. "Text",
  2612. "Link",
  2613. "FreeText",
  2614. "Line",
  2615. "Square",
  2616. "Circle",
  2617. "Polygon",
  2618. "PolyLine",
  2619. "Highlight",
  2620. "Underline",
  2621. "Squiggly",
  2622. "StrikeOut",
  2623. "Redact",
  2624. "Stamp",
  2625. "Caret",
  2626. "Ink",
  2627. "Popup",
  2628. "FileAttachment",
  2629. "Sound",
  2630. "Movie",
  2631. "RichMedia",
  2632. "Widget",
  2633. "Screen",
  2634. "PrinterMark",
  2635. "TrapNet",
  2636. "Watermark",
  2637. "3D",
  2638. "Projection",
  2639. ]
  2640. static readonly LINE_ENDING: PDFAnnotationLineEndingStyle[] = [
  2641. "None",
  2642. "Square",
  2643. "Circle",
  2644. "Diamond",
  2645. "OpenArrow",
  2646. "ClosedArrow",
  2647. "Butt",
  2648. "ROpenArrow",
  2649. "RClosedArrow",
  2650. "Slash",
  2651. ]
  2652. static readonly BORDER_STYLE: PDFAnnotationBorderStyle[] = [ "Solid", "Dashed", "Beveled", "Inset", "Underline" ]
  2653. static readonly BORDER_EFFECT: PDFAnnotationBorderEffect[] = [ "None", "Cloudy" ]
  2654. static readonly INTENT: PDFAnnotationIntent[] = [
  2655. null,
  2656. "FreeTextCallout",
  2657. "FreeTextTypeWriter",
  2658. "LineArrow",
  2659. "LineDimension",
  2660. "PloyLine",
  2661. "PolygonCloud",
  2662. "PolygonDimension",
  2663. "StampImage",
  2664. "StampSnapshot"
  2665. ]
  2666. // Bit masks for getFlags and setFlags
  2667. static readonly IS_INVISIBLE = 1 << (1 - 1)
  2668. static readonly IS_HIDDEN = 1 << (2 - 1)
  2669. static readonly IS_PRINT = 1 << (3 - 1)
  2670. static readonly IS_NO_ZOOM = 1 << (4 - 1)
  2671. static readonly IS_NO_ROTATE = 1 << (5 - 1)
  2672. static readonly IS_NO_VIEW = 1 << (6 - 1)
  2673. static readonly IS_READ_ONLY = 1 << (7 - 1)
  2674. static readonly IS_LOCKED = 1 << (8 - 1)
  2675. static readonly IS_TOGGLE_NO_VIEW = 1 << (9 - 1)
  2676. static readonly IS_LOCKED_CONTENTS = 1 << (10 - 1)
  2677. // PRIVATE
  2678. constructor(doc: PDFDocument, pointer: Pointer<"pdf_annot">) {
  2679. super(pointer)
  2680. this._doc = doc
  2681. }
  2682. getObject() {
  2683. return this._doc._fromPDFObjectKeep(libmupdf._wasm_pdf_annot_obj(this.pointer))
  2684. }
  2685. getBounds() {
  2686. return fromRect(libmupdf._wasm_pdf_bound_annot(this.pointer))
  2687. }
  2688. run(device: Device, matrix: Matrix) {
  2689. checkType(device, Device)
  2690. checkMatrix(matrix)
  2691. libmupdf._wasm_pdf_run_annot(this.pointer, device.pointer, MATRIX(matrix))
  2692. }
  2693. toPixmap(matrix: Matrix, colorspace: ColorSpace, alpha = false) {
  2694. checkMatrix(matrix)
  2695. checkType(colorspace, ColorSpace)
  2696. return new Pixmap(
  2697. libmupdf._wasm_pdf_new_pixmap_from_annot(
  2698. this.pointer,
  2699. MATRIX(matrix),
  2700. colorspace.pointer,
  2701. alpha)
  2702. )
  2703. }
  2704. toDisplayList() {
  2705. return new DisplayList(libmupdf._wasm_pdf_new_display_list_from_annot(this.pointer))
  2706. }
  2707. update() {
  2708. return !!libmupdf._wasm_pdf_update_annot(this.pointer)
  2709. }
  2710. getType() {
  2711. let type = libmupdf._wasm_pdf_annot_type(this.pointer)
  2712. return PDFAnnotation.ANNOT_TYPES[type] || "Text"
  2713. }
  2714. getLanguage() {
  2715. return fromString(libmupdf._wasm_pdf_annot_language(this.pointer))
  2716. }
  2717. setLanguage(lang: string) {
  2718. libmupdf._wasm_pdf_set_annot_language(this.pointer, STRING(lang))
  2719. }
  2720. getFlags() {
  2721. return libmupdf._wasm_pdf_annot_flags(this.pointer)
  2722. }
  2723. setFlags(flags: number) {
  2724. return libmupdf._wasm_pdf_set_annot_flags(this.pointer, flags)
  2725. }
  2726. getContents() {
  2727. return fromString(libmupdf._wasm_pdf_annot_contents(this.pointer))
  2728. }
  2729. setContents(text: string) {
  2730. libmupdf._wasm_pdf_set_annot_contents(this.pointer, STRING(text))
  2731. }
  2732. getAuthor() {
  2733. return fromString(libmupdf._wasm_pdf_annot_author(this.pointer))
  2734. }
  2735. setAuthor(text: string) {
  2736. libmupdf._wasm_pdf_set_annot_author(this.pointer, STRING(text))
  2737. }
  2738. getCreationDate() {
  2739. return new Date(libmupdf._wasm_pdf_annot_creation_date(this.pointer) * 1000)
  2740. }
  2741. setCreationDate(date: Date) {
  2742. checkType(date, Date)
  2743. libmupdf._wasm_pdf_set_annot_creation_date(this.pointer, date.getTime() / 1000)
  2744. }
  2745. getModificationDate() {
  2746. return new Date(libmupdf._wasm_pdf_annot_modification_date(this.pointer) * 1000)
  2747. }
  2748. setModificationDate(date: Date) {
  2749. checkType(date, Date)
  2750. libmupdf._wasm_pdf_set_annot_modification_date(this.pointer, date.getTime() / 1000)
  2751. }
  2752. hasRect() {
  2753. return !!libmupdf._wasm_pdf_annot_has_rect(this.pointer)
  2754. }
  2755. hasInkList() {
  2756. return !!libmupdf._wasm_pdf_annot_has_ink_list(this.pointer)
  2757. }
  2758. hasQuadPoints() {
  2759. return !!libmupdf._wasm_pdf_annot_has_quad_points(this.pointer)
  2760. }
  2761. hasVertices() {
  2762. return !!libmupdf._wasm_pdf_annot_has_vertices(this.pointer)
  2763. }
  2764. hasLine() {
  2765. return !!libmupdf._wasm_pdf_annot_has_line(this.pointer)
  2766. }
  2767. hasInteriorColor() {
  2768. return !!libmupdf._wasm_pdf_annot_has_interior_color(this.pointer)
  2769. }
  2770. hasLineEndingStyles() {
  2771. return !!libmupdf._wasm_pdf_annot_has_line_ending_styles(this.pointer)
  2772. }
  2773. hasBorder() {
  2774. return !!libmupdf._wasm_pdf_annot_has_border(this.pointer)
  2775. }
  2776. hasBorderEffect() {
  2777. return !!libmupdf._wasm_pdf_annot_has_border_effect(this.pointer)
  2778. }
  2779. hasIcon() {
  2780. return !!libmupdf._wasm_pdf_annot_has_icon_name(this.pointer)
  2781. }
  2782. hasOpen() {
  2783. return !!libmupdf._wasm_pdf_annot_has_open(this.pointer)
  2784. }
  2785. hasAuthor() {
  2786. return !!libmupdf._wasm_pdf_annot_has_author(this.pointer)
  2787. }
  2788. hasFilespec() {
  2789. return !!libmupdf._wasm_pdf_annot_has_filespec(this.pointer)
  2790. }
  2791. hasCallout() {
  2792. return !!libmupdf._wasm_pdf_annot_has_callout(this.pointer)
  2793. }
  2794. hasRichContents() {
  2795. return !!libmupdf._wasm_pdf_annot_has_rich_contents(this.pointer)
  2796. }
  2797. getRect() {
  2798. return fromRect(libmupdf._wasm_pdf_annot_rect(this.pointer))
  2799. }
  2800. setRect(rect: Rect) {
  2801. checkRect(rect)
  2802. libmupdf._wasm_pdf_set_annot_rect(this.pointer, RECT(rect))
  2803. }
  2804. getPopup() {
  2805. return fromRect(libmupdf._wasm_pdf_annot_popup(this.pointer))
  2806. }
  2807. setPopup(rect: Rect) {
  2808. checkRect(rect)
  2809. libmupdf._wasm_pdf_set_annot_popup(this.pointer, RECT(rect))
  2810. }
  2811. getIsOpen() {
  2812. return !!libmupdf._wasm_pdf_annot_is_open(this.pointer)
  2813. }
  2814. setIsOpen(isOpen: boolean) {
  2815. checkType(isOpen, "boolean")
  2816. libmupdf._wasm_pdf_set_annot_is_open(this.pointer, isOpen)
  2817. }
  2818. getHiddenForEditing() {
  2819. return !!libmupdf._wasm_pdf_annot_hidden_for_editing(this.pointer)
  2820. }
  2821. setHiddenForEditing(isHidden: boolean) {
  2822. checkType(isHidden, "boolean")
  2823. libmupdf._wasm_pdf_set_annot_hidden_for_editing(this.pointer, isHidden)
  2824. }
  2825. getIcon() {
  2826. return fromString(libmupdf._wasm_pdf_annot_icon_name(this.pointer))
  2827. }
  2828. setIcon(text: string) {
  2829. checkType(text, "string")
  2830. libmupdf._wasm_pdf_set_annot_icon_name(this.pointer, STRING(text))
  2831. }
  2832. getOpacity() {
  2833. return libmupdf._wasm_pdf_annot_opacity(this.pointer)
  2834. }
  2835. setOpacity(opacity: number) {
  2836. checkType(opacity, "number")
  2837. libmupdf._wasm_pdf_set_annot_opacity(this.pointer, opacity)
  2838. }
  2839. getQuadding() {
  2840. return libmupdf._wasm_pdf_annot_quadding(this.pointer)
  2841. }
  2842. setQuadding(quadding: number) {
  2843. checkType(quadding, "number")
  2844. libmupdf._wasm_pdf_set_annot_quadding(this.pointer, quadding)
  2845. }
  2846. getLine() {
  2847. let a = fromPoint(libmupdf._wasm_pdf_annot_line_1(this.pointer))
  2848. let b = fromPoint(libmupdf._wasm_pdf_annot_line_2(this.pointer))
  2849. return [ a, b ]
  2850. }
  2851. setLine(a: Point, b: Point) {
  2852. checkPoint(a)
  2853. checkPoint(b)
  2854. libmupdf._wasm_pdf_set_annot_line(this.pointer, POINT(a), POINT2(b))
  2855. }
  2856. getLineEndingStyles() {
  2857. let a = libmupdf._wasm_pdf_annot_line_ending_styles_start(this.pointer)
  2858. let b = libmupdf._wasm_pdf_annot_line_ending_styles_end(this.pointer)
  2859. return {
  2860. start: PDFAnnotation.LINE_ENDING[a] || "None",
  2861. end: PDFAnnotation.LINE_ENDING[b] || "None",
  2862. }
  2863. }
  2864. setLineEndingStyles(start: PDFAnnotationLineEndingStyle, end: PDFAnnotationLineEndingStyle) {
  2865. let start_ix = ENUM<PDFAnnotationLineEndingStyle>(start, PDFAnnotation.LINE_ENDING)
  2866. let end_ix = ENUM<PDFAnnotationLineEndingStyle>(end, PDFAnnotation.LINE_ENDING)
  2867. libmupdf._wasm_pdf_set_annot_line_ending_styles(this.pointer, start_ix, end_ix)
  2868. }
  2869. getLineCaption() {
  2870. return libmupdf._wasm_pdf_annot_line_caption(this.pointer)
  2871. }
  2872. setLineCaption(on: boolean) {
  2873. return libmupdf._wasm_pdf_set_annot_line_caption(this.pointer, on)
  2874. }
  2875. getLineCaptionOffset() {
  2876. return fromPoint(libmupdf._wasm_pdf_annot_line_caption_offset(this.pointer))
  2877. }
  2878. setLineCaptionOffset(p: Point) {
  2879. return libmupdf._wasm_pdf_set_annot_line_caption_offset(this.pointer, POINT(p))
  2880. }
  2881. getLineLeader() {
  2882. return libmupdf._wasm_pdf_annot_line_leader(this.pointer)
  2883. }
  2884. getLineLeaderExtension() {
  2885. return libmupdf._wasm_pdf_annot_line_leader_extension(this.pointer)
  2886. }
  2887. getLineLeaderOffset() {
  2888. return libmupdf._wasm_pdf_annot_line_leader_offset(this.pointer)
  2889. }
  2890. setLineLeader(v: number) {
  2891. return libmupdf._wasm_pdf_set_annot_line_leader(this.pointer, v)
  2892. }
  2893. setLineLeaderExtension(v: number) {
  2894. return libmupdf._wasm_pdf_set_annot_line_leader_extension(this.pointer, v)
  2895. }
  2896. setLineLeaderOffset(v: number) {
  2897. return libmupdf._wasm_pdf_set_annot_line_leader_offset(this.pointer, v)
  2898. }
  2899. getCalloutStyle() {
  2900. let style = libmupdf._wasm_pdf_annot_callout_style(this.pointer)
  2901. return PDFAnnotation.LINE_ENDING[style] || "None"
  2902. }
  2903. setCalloutStyle(style: PDFAnnotationLineEndingStyle) {
  2904. let style_ix = ENUM<PDFAnnotationLineEndingStyle>(style, PDFAnnotation.LINE_ENDING)
  2905. libmupdf._wasm_pdf_set_annot_callout_style(this.pointer, style_ix)
  2906. }
  2907. getCalloutLine() {
  2908. let n = libmupdf._wasm_pdf_annot_callout_line(this.pointer,
  2909. (_wasm_point << 2) as Pointer<"fz_point">)
  2910. if (n == 3)
  2911. return [
  2912. fromPoint((_wasm_point+0) << 2 as Pointer<"fz_point">),
  2913. fromPoint((_wasm_point+1) << 2 as Pointer<"fz_point">),
  2914. fromPoint((_wasm_point+2) << 2 as Pointer<"fz_point">)
  2915. ]
  2916. if (n == 2)
  2917. return [
  2918. fromPoint((_wasm_point+0) << 2 as Pointer<"fz_point">),
  2919. fromPoint((_wasm_point+1) << 2 as Pointer<"fz_point">)
  2920. ]
  2921. return undefined
  2922. }
  2923. setCalloutLine(line: Point[]) {
  2924. let a = line[0] || [0, 0]
  2925. let b = line[1] || [0, 0]
  2926. let c = line[2] || [0, 0]
  2927. libmupdf._wasm_pdf_set_annot_callout_line(this.pointer, line.length, POINT(a), POINT2(b), POINT3(c))
  2928. }
  2929. getCalloutPoint() {
  2930. let line = this.getCalloutLine()
  2931. if (line)
  2932. return line[0]
  2933. return undefined
  2934. }
  2935. setCalloutPoint(p: Point) {
  2936. libmupdf._wasm_pdf_set_annot_callout_point(this.pointer, POINT(p))
  2937. }
  2938. getColor() {
  2939. return fromColor(libmupdf._wasm_pdf_annot_color(this.pointer, COLOR()))
  2940. }
  2941. getInteriorColor() {
  2942. return fromColor(libmupdf._wasm_pdf_annot_interior_color(this.pointer, COLOR()))
  2943. }
  2944. setColor(color: Color) {
  2945. checkColor(color)
  2946. libmupdf._wasm_pdf_set_annot_color(this.pointer, color.length, COLOR(color))
  2947. }
  2948. setInteriorColor(color: Color) {
  2949. checkColor(color)
  2950. libmupdf._wasm_pdf_set_annot_interior_color(this.pointer, color.length, COLOR(color))
  2951. }
  2952. getBorderWidth() {
  2953. return libmupdf._wasm_pdf_annot_border_width(this.pointer)
  2954. }
  2955. setBorderWidth(value: number) {
  2956. checkType(value, "number")
  2957. return libmupdf._wasm_pdf_set_annot_border_width(this.pointer, value)
  2958. }
  2959. getBorderStyle() {
  2960. return PDFAnnotation.BORDER_STYLE[libmupdf._wasm_pdf_annot_border_style(this.pointer)] || "Solid"
  2961. }
  2962. setBorderStyle(value: PDFAnnotationBorderStyle) {
  2963. let value_ix = ENUM<PDFAnnotationBorderStyle>(value, PDFAnnotation.BORDER_STYLE)
  2964. return libmupdf._wasm_pdf_set_annot_border_style(this.pointer, value_ix)
  2965. }
  2966. getBorderEffect() {
  2967. return PDFAnnotation.BORDER_EFFECT[libmupdf._wasm_pdf_annot_border_effect(this.pointer)] || "None"
  2968. }
  2969. setBorderEffect(value: PDFAnnotationBorderEffect) {
  2970. let value_ix = ENUM<PDFAnnotationBorderEffect>(value, PDFAnnotation.BORDER_EFFECT)
  2971. return libmupdf._wasm_pdf_set_annot_border_effect(this.pointer, value_ix)
  2972. }
  2973. getBorderEffectIntensity() {
  2974. return libmupdf._wasm_pdf_annot_border_effect_intensity(this.pointer)
  2975. }
  2976. setBorderEffectIntensity(value: number) {
  2977. checkType(value, "number")
  2978. return libmupdf._wasm_pdf_set_annot_border_effect_intensity(this.pointer, value)
  2979. }
  2980. getBorderDashCount() {
  2981. return libmupdf._wasm_pdf_annot_border_dash_count(this.pointer)
  2982. }
  2983. getBorderDashItem(idx: number) {
  2984. return libmupdf._wasm_pdf_annot_border_dash_item(this.pointer, idx)
  2985. }
  2986. clearBorderDash() {
  2987. return libmupdf._wasm_pdf_clear_annot_border_dash(this.pointer)
  2988. }
  2989. addBorderDashItem(v: number) {
  2990. checkType(v, "number")
  2991. return libmupdf._wasm_pdf_add_annot_border_dash_item(this.pointer, v)
  2992. }
  2993. getBorderDashPattern() {
  2994. let n = this.getBorderDashCount()
  2995. let result = new Array(n)
  2996. for (let i = 0; i < n; ++i)
  2997. result[i] = this.getBorderDashItem(i)
  2998. return result
  2999. }
  3000. setBorderDashPattern(list: number[]) {
  3001. this.clearBorderDash()
  3002. for (let v of list)
  3003. this.addBorderDashItem(v)
  3004. }
  3005. getIntent(): PDFAnnotationIntent {
  3006. return PDFAnnotation.INTENT[libmupdf._wasm_pdf_annot_intent(this.pointer)] || null
  3007. }
  3008. setIntent(value: PDFAnnotationIntent) {
  3009. let value_ix = ENUM<PDFAnnotationIntent>(value, PDFAnnotation.INTENT)
  3010. return libmupdf._wasm_pdf_set_annot_intent(this.pointer, value_ix)
  3011. }
  3012. setDefaultAppearance(fontName: string, size: number, color: Color) {
  3013. checkType(fontName, "string")
  3014. checkType(size, "number")
  3015. checkColor(color)
  3016. libmupdf._wasm_pdf_set_annot_default_appearance(this.pointer, STRING(fontName), size, color.length, COLOR(color))
  3017. }
  3018. getDefaultAppearance() {
  3019. let font = fromString(libmupdf._wasm_pdf_annot_default_appearance_font(this.pointer))
  3020. let size = libmupdf._wasm_pdf_annot_default_appearance_size(this.pointer)
  3021. let color = fromColor(libmupdf._wasm_pdf_annot_default_appearance_color(this.pointer, COLOR()))
  3022. return { font, size, color }
  3023. }
  3024. getFileSpec() {
  3025. return this._doc._fromPDFObjectKeep(libmupdf._wasm_pdf_annot_filespec(this.pointer))
  3026. }
  3027. setFileSpec(fs: PDFObject) {
  3028. return libmupdf._wasm_pdf_set_annot_filespec(this.pointer, this._doc._PDFOBJ(fs))
  3029. }
  3030. getQuadPoints() {
  3031. let n = libmupdf._wasm_pdf_annot_quad_point_count(this.pointer)
  3032. let result: Quad[] = []
  3033. for (let i = 0; i < n; ++i)
  3034. result.push(fromQuad(libmupdf._wasm_pdf_annot_quad_point(this.pointer, i)))
  3035. return result
  3036. }
  3037. clearQuadPoints() {
  3038. libmupdf._wasm_pdf_clear_annot_quad_points(this.pointer)
  3039. }
  3040. addQuadPoint(quad: Quad) {
  3041. checkQuad(quad)
  3042. libmupdf._wasm_pdf_add_annot_quad_point(this.pointer, QUAD(quad))
  3043. }
  3044. setQuadPoints(quadlist: Quad[]) {
  3045. this.clearQuadPoints()
  3046. for (let quad of quadlist)
  3047. this.addQuadPoint(quad)
  3048. }
  3049. getVertices() {
  3050. let n = libmupdf._wasm_pdf_annot_vertex_count(this.pointer)
  3051. let result: Point[] = new Array(n)
  3052. for (let i = 0; i < n; ++i)
  3053. result[i] = fromPoint(libmupdf._wasm_pdf_annot_vertex(this.pointer, i))
  3054. return result
  3055. }
  3056. clearVertices() {
  3057. libmupdf._wasm_pdf_clear_annot_vertices(this.pointer)
  3058. }
  3059. addVertex(vertex: Point) {
  3060. checkPoint(vertex)
  3061. libmupdf._wasm_pdf_add_annot_vertex(this.pointer, POINT(vertex))
  3062. }
  3063. setVertices(vertexlist: Point[]) {
  3064. this.clearVertices()
  3065. for (let vertex of vertexlist)
  3066. this.addVertex(vertex)
  3067. }
  3068. getInkList() {
  3069. let n = libmupdf._wasm_pdf_annot_ink_list_count(this.pointer)
  3070. let outer: Point[][] = []
  3071. for (let i = 0; i < n; ++i) {
  3072. let m = libmupdf._wasm_pdf_annot_ink_list_stroke_count(this.pointer, i)
  3073. let inner: Point[] = new Array(m)
  3074. for (let k = 0; k < m; ++k)
  3075. inner[k] = fromPoint(libmupdf._wasm_pdf_annot_ink_list_stroke_vertex(this.pointer, i, k))
  3076. outer.push(inner)
  3077. }
  3078. return outer
  3079. }
  3080. clearInkList() {
  3081. libmupdf._wasm_pdf_clear_annot_ink_list(this.pointer)
  3082. }
  3083. addInkListStroke() {
  3084. libmupdf._wasm_pdf_add_annot_ink_list_stroke(this.pointer)
  3085. }
  3086. addInkListStrokeVertex(v: Point) {
  3087. checkPoint(v)
  3088. libmupdf._wasm_pdf_add_annot_ink_list_stroke_vertex(this.pointer, POINT(v))
  3089. }
  3090. setInkList(inklist: Point[][]) {
  3091. this.clearInkList()
  3092. for (let stroke of inklist) {
  3093. this.addInkListStroke()
  3094. for (let vertex of stroke)
  3095. this.addInkListStrokeVertex(vertex)
  3096. }
  3097. }
  3098. getRichContents() {
  3099. return fromString(libmupdf._wasm_pdf_annot_rich_contents(this.pointer))
  3100. }
  3101. setRichContents(plain: string, html: string) {
  3102. checkType(plain, "string")
  3103. checkType(html, "string")
  3104. libmupdf._wasm_pdf_set_annot_rich_contents(this.pointer, STRING(plain), STRING2(html))
  3105. }
  3106. getRichDefaults() {
  3107. return fromString(libmupdf._wasm_pdf_annot_rich_defaults(this.pointer))
  3108. }
  3109. setRichDefaults(style: string) {
  3110. checkType(style, "string")
  3111. libmupdf._wasm_pdf_set_annot_rich_defaults(this.pointer, STRING(style))
  3112. }
  3113. setStampImage(image: Image) {
  3114. libmupdf._wasm_pdf_set_annot_stamp_image(this.pointer, image.pointer)
  3115. }
  3116. setAppearanceFromDisplayList(appearance: string | null, state: string | null, transform: Matrix, list: DisplayList) {
  3117. checkMatrix(transform)
  3118. checkType(list, DisplayList)
  3119. libmupdf._wasm_pdf_set_annot_appearance_from_display_list(
  3120. this.pointer,
  3121. STRING_OPT(appearance),
  3122. STRING2_OPT(state),
  3123. MATRIX(transform),
  3124. list.pointer
  3125. )
  3126. }
  3127. setAppearance(appearance: string | null, state: string | null, transform: Matrix, bbox: Rect, resources: any, contents: AnyBuffer) {
  3128. checkMatrix(transform)
  3129. checkRect(bbox)
  3130. libmupdf._wasm_pdf_set_annot_appearance(
  3131. this.pointer,
  3132. STRING_OPT(appearance),
  3133. STRING2_OPT(state),
  3134. MATRIX(transform),
  3135. RECT(bbox),
  3136. this._doc._PDFOBJ(resources),
  3137. BUFFER(contents)
  3138. )
  3139. }
  3140. applyRedaction(black_boxes = 1, image_method = 2, line_art_method = 1, text_method = 0) {
  3141. libmupdf._wasm_pdf_apply_redaction(this.pointer, black_boxes, image_method, line_art_method, text_method)
  3142. }
  3143. }
  3144. export class PDFWidget extends PDFAnnotation {
  3145. /* IMPORTANT: Keep in sync with mupdf/pdf/widget.h and PDFWidget.java */
  3146. static readonly WIDGET_TYPES = [
  3147. "widget", // unknown
  3148. "button",
  3149. "checkbox",
  3150. "combobox",
  3151. "listbox",
  3152. "radiobutton",
  3153. "signature",
  3154. "text",
  3155. ]
  3156. /* Field flags */
  3157. static readonly FIELD_IS_READ_ONLY = 1
  3158. static readonly FIELD_IS_REQUIRED = 1 << 1
  3159. static readonly FIELD_IS_NO_EXPORT = 1 << 2
  3160. /* Text fields */
  3161. static readonly TX_FIELD_IS_MULTILINE = 1 << 12
  3162. static readonly TX_FIELD_IS_PASSWORD = 1 << 13
  3163. static readonly TX_FIELD_IS_COMB = 1 << 24
  3164. /* Button fields */
  3165. static readonly BTN_FIELD_IS_NO_TOGGLE_TO_OFF = 1 << 14
  3166. static readonly BTN_FIELD_IS_RADIO = 1 << 15
  3167. static readonly BTN_FIELD_IS_PUSHBUTTON = 1 << 16
  3168. /* Choice fields */
  3169. static readonly CH_FIELD_IS_COMBO = 1 << 17
  3170. static readonly CH_FIELD_IS_EDIT = 1 << 18
  3171. static readonly CH_FIELD_IS_SORT = 1 << 19
  3172. static readonly CH_FIELD_IS_MULTI_SELECT = 1 << 21
  3173. getFieldType() {
  3174. return PDFWidget.WIDGET_TYPES[libmupdf._wasm_pdf_annot_field_type(this.pointer)] || "button"
  3175. }
  3176. isButton() {
  3177. let type = this.getFieldType()
  3178. return type === "button" || type === "checkbox" || type === "radiobutton"
  3179. }
  3180. isPushButton() {
  3181. return this.getFieldType() === "button"
  3182. }
  3183. isCheckbox() {
  3184. return this.getFieldType() === "checkbox"
  3185. }
  3186. isRadioButton() {
  3187. return this.getFieldType() === "radiobutton"
  3188. }
  3189. isText() {
  3190. return this.getFieldType() === "text"
  3191. }
  3192. isChoice() {
  3193. let type = this.getFieldType()
  3194. return type === "combobox" || type === "listbox"
  3195. }
  3196. isListBox() {
  3197. return this.getFieldType() === "listbox"
  3198. }
  3199. isComboBox() {
  3200. return this.getFieldType() === "combobox"
  3201. }
  3202. getFieldFlags() {
  3203. return libmupdf._wasm_pdf_annot_field_flags(this.pointer)
  3204. }
  3205. isMultiline() {
  3206. return (this.getFieldFlags() & PDFWidget.TX_FIELD_IS_MULTILINE) !== 0
  3207. }
  3208. isPassword() {
  3209. return (this.getFieldFlags() & PDFWidget.TX_FIELD_IS_PASSWORD) !== 0
  3210. }
  3211. isComb() {
  3212. return (this.getFieldFlags() & PDFWidget.TX_FIELD_IS_COMB) !== 0
  3213. }
  3214. isReadOnly() {
  3215. return (this.getFieldFlags() & PDFWidget.FIELD_IS_READ_ONLY) !== 0
  3216. }
  3217. getLabel() {
  3218. return fromString(libmupdf._wasm_pdf_annot_field_label(this.pointer))
  3219. }
  3220. getName() {
  3221. return fromStringFree(libmupdf._wasm_pdf_load_field_name(this.pointer))
  3222. }
  3223. getValue() {
  3224. return fromString(libmupdf._wasm_pdf_annot_field_value(this.pointer))
  3225. }
  3226. setTextValue(value: string) {
  3227. libmupdf._wasm_pdf_set_annot_text_field_value(this.pointer, STRING(value))
  3228. }
  3229. getMaxLen() {
  3230. return libmupdf._wasm_pdf_annot_text_widget_max_len(this.pointer)
  3231. }
  3232. setChoiceValue(value: string) {
  3233. libmupdf._wasm_pdf_set_annot_choice_field_value(this.pointer, STRING(value))
  3234. }
  3235. getOptions(isExport=false) {
  3236. let result: string[] = []
  3237. let n = libmupdf._wasm_pdf_annot_choice_field_option_count(this.pointer)
  3238. for (let i = 0; i < n; ++i) {
  3239. result.push(
  3240. fromString(
  3241. libmupdf._wasm_pdf_annot_choice_field_option(this.pointer, isExport, i)
  3242. )
  3243. )
  3244. }
  3245. return result
  3246. }
  3247. toggle() {
  3248. libmupdf._wasm_pdf_toggle_widget(this.pointer)
  3249. }
  3250. // Interactive Text Widget editing in a GUI.
  3251. // TODO: getEditingState()
  3252. // TODO: setEditingState()
  3253. // TODO: clearEditingState()
  3254. // TODO: layoutTextWidget()
  3255. // Interactive form validation Javascript triggers.
  3256. // NOTE: No embedded PDF Javascript engine in WASM build.
  3257. // TODO: eventEnter()
  3258. // TODO: eventExit()
  3259. // TODO: eventDown()
  3260. // TODO: eventUp()
  3261. // TODO: eventFocus()
  3262. // TODO: eventBlur()
  3263. // NOTE: No OpenSSL support in WASM build.
  3264. // TODO: isSigned()
  3265. // TODO: validateSignature()
  3266. // TODO: checkCertificate()
  3267. // TODO: checkDigest()
  3268. // TODO: getSignature()
  3269. // TODO: previewSignature()
  3270. // TODO: clearSignature()
  3271. // TODO: sign()
  3272. }
  3273. /* -------------------------------------------------------------------------- */
  3274. /* We need a certain level of ugliness to allow callbacks from C to JS */
  3275. declare global {
  3276. function $libmupdf_stm_close(ptr: number): void
  3277. function $libmupdf_stm_seek(ptr: number, pos: number, offset: number, whence: number): number
  3278. function $libmupdf_stm_read(ptr: number, pos: number, addr: number, size: number): number
  3279. }
  3280. interface StreamHandle {
  3281. fileSize(): number,
  3282. read(memory: Uint8Array, offset: number, length: number, position: number): number,
  3283. close(): void,
  3284. }
  3285. var $libmupdf_stm_id = 0
  3286. var $libmupdf_stm_table: Map<number,StreamHandle> = new Map()
  3287. globalThis.$libmupdf_stm_close = function (id: number) {
  3288. let handle = $libmupdf_stm_table.get(id)
  3289. if (handle) {
  3290. handle.close()
  3291. $libmupdf_stm_table.delete(id)
  3292. return
  3293. }
  3294. throw new Error("invalid file handle")
  3295. }
  3296. globalThis.$libmupdf_stm_seek = function (id: number, pos: number, offset: number, whence: number) {
  3297. let handle = $libmupdf_stm_table.get(id)
  3298. if (handle) {
  3299. if (whence === 0)
  3300. return offset
  3301. if (whence === 1)
  3302. return pos + offset
  3303. if (whence === 2) {
  3304. let size = handle.fileSize()
  3305. if (size < 0)
  3306. return -1
  3307. return size + offset
  3308. }
  3309. throw new Error("invalid whence argument")
  3310. }
  3311. throw new Error("invalid file handle")
  3312. }
  3313. globalThis.$libmupdf_stm_read = function (id: number, pos: number, addr: number, size: number) {
  3314. let handle = $libmupdf_stm_table.get(id)
  3315. if (handle) {
  3316. return handle.read(libmupdf.HEAPU8, addr, size, pos)
  3317. }
  3318. throw new Error("invalid file handle")
  3319. }
  3320. export class Stream extends Userdata<"fz_stream"> {
  3321. static override readonly _drop = libmupdf._wasm_drop_stream
  3322. constructor(handle: StreamHandle) {
  3323. let id = $libmupdf_stm_id++
  3324. $libmupdf_stm_table.set(id, handle)
  3325. super(libmupdf._wasm_new_stream(id))
  3326. }
  3327. }
  3328. /* -------------------------------------------------------------------------- */
  3329. var $libmupdf_load_font_file_js: (name: string, script: string, bold: boolean, italic: boolean) => Font | null
  3330. declare global {
  3331. function $libmupdf_load_font_file(name: Pointer<"char">, script: Pointer<"char">, bold: boolean, italic: boolean): Pointer<"fz_font">
  3332. }
  3333. globalThis.$libmupdf_load_font_file = function (name, script, bold, italic) {
  3334. if ($libmupdf_load_font_file_js) {
  3335. var font = $libmupdf_load_font_file_js(fromString(name), fromString(script), bold, italic)
  3336. if (font) {
  3337. checkType(font, Font)
  3338. return font.pointer
  3339. }
  3340. }
  3341. return 0 as Pointer<"fz_font">
  3342. }
  3343. interface DeviceFunctions {
  3344. drop?(): void,
  3345. close?(): void,
  3346. fillPath?(path: Path, evenOdd: boolean, ctm: Matrix, colorspace: ColorSpace, color: number[], alpha: number): void,
  3347. strokePath?(path: Path, stroke: StrokeState, ctm: Matrix, colorspace: ColorSpace, color: number[], alpha: number): void,
  3348. clipPath?(path: Path, evenOdd: boolean, ctm: Matrix): void,
  3349. clipStrokePath?(path: Path, stroke: StrokeState, ctm: Matrix): void,
  3350. fillText?(text: Text, ctm: Matrix, colorspace: ColorSpace, color: number[], alpha: number): void,
  3351. strokeText?(text: Text, stroke: StrokeState, ctm: Matrix, colorspace: ColorSpace, color: number[], alpha: number): void,
  3352. clipText?(text: Text, ctm: Matrix): void,
  3353. clipStrokeText?(text: Text, stroke: StrokeState, ctm: Matrix): void,
  3354. ignoreText?(text: Text, ctm: Matrix): void,
  3355. fillShade?(shade: Shade, ctm: Matrix, alpha: number): void,
  3356. fillImage?(image: Image, ctm: Matrix, alpha: number): void,
  3357. fillImageMask?(image: Image, ctm: Matrix, colorspace: ColorSpace, color: number[], alpha: number): void,
  3358. clipImageMask?(image: Image, ctm: Matrix): void,
  3359. popClip?(): void,
  3360. beginMask?(bbox: Rect, luminosity: boolean, colorspace: ColorSpace, color: number[]): void,
  3361. endMask?(): void,
  3362. beginGroup?(bbox: Rect, colorspace: ColorSpace, isolated: boolean, knockout: boolean, blendmode: BlendMode, alpha: number): void,
  3363. endGroup?(): void,
  3364. beginTile?(area: Rect, view: Rect, xstep: number, ystep: number, ctm: Matrix, id: number): number,
  3365. endTile?(): void,
  3366. beginLayer?(name: string): void,
  3367. endLayer?(): void,
  3368. }
  3369. var $libmupdf_device_id = 0
  3370. var $libmupdf_device_table: Map<number,DeviceFunctions> = new Map()
  3371. var $libmupdf_path_id = 0
  3372. var $libmupdf_path_table: Map<number,PathWalker> = new Map()
  3373. var $libmupdf_text_id = 0
  3374. var $libmupdf_text_table: Map<number,TextWalker> = new Map()
  3375. declare global {
  3376. var $libmupdf_path_walk: any
  3377. var $libmupdf_text_walk: any
  3378. var $libmupdf_device: any
  3379. }
  3380. globalThis.$libmupdf_path_walk = {
  3381. moveto(id: number, x: number, y: number): void {
  3382. $libmupdf_path_table.get(id)?.moveTo?.(x, y)
  3383. },
  3384. lineto(id: number, x: number, y: number): void {
  3385. $libmupdf_path_table.get(id)?.lineTo?.(x, y)
  3386. },
  3387. curveto(id: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void {
  3388. $libmupdf_path_table.get(id)?.curveTo?.(x1, y1, x2, y2, x3, y3)
  3389. },
  3390. closepath(id: number): void {
  3391. $libmupdf_path_table.get(id)?.closePath?.()
  3392. },
  3393. }
  3394. var $libmupdf_text_font: Font | null = null
  3395. globalThis.$libmupdf_text_walk = {
  3396. begin_span(
  3397. id: number,
  3398. font: Pointer<"fz_font">,
  3399. trm: Pointer<"fz_matrix">,
  3400. wmode: number,
  3401. bidi: number,
  3402. dir: number,
  3403. lang: Pointer<"char">
  3404. ): void {
  3405. if (font !== $libmupdf_text_font?.pointer)
  3406. $libmupdf_text_font = new Font(font)
  3407. $libmupdf_text_table.get(id)?.beginSpan?.(
  3408. $libmupdf_text_font,
  3409. fromMatrix(trm),
  3410. wmode,
  3411. bidi,
  3412. dir,
  3413. fromString(lang)
  3414. )
  3415. },
  3416. end_span(id: number): void {
  3417. $libmupdf_text_table.get(id)?.endSpan?.()
  3418. },
  3419. show_glyph(
  3420. id: number,
  3421. font: Pointer<"fz_font">,
  3422. trm: Pointer<"fz_matrix">,
  3423. glyph: number,
  3424. unicode: number,
  3425. wmode: number,
  3426. bidi: number
  3427. ): void {
  3428. if (font !== $libmupdf_text_font?.pointer)
  3429. $libmupdf_text_font = new Font(font)
  3430. $libmupdf_text_table.get(id)?.showGlyph?.(
  3431. $libmupdf_text_font,
  3432. fromMatrix(trm),
  3433. glyph,
  3434. unicode,
  3435. wmode,
  3436. bidi
  3437. )
  3438. },
  3439. }
  3440. globalThis.$libmupdf_device = {
  3441. drop_device(id: number): void {
  3442. $libmupdf_device_table.get(id)?.drop?.()
  3443. $libmupdf_device_table.delete(id)
  3444. },
  3445. close_device(id: number): void {
  3446. $libmupdf_device_table.get(id)?.close?.()
  3447. },
  3448. fill_path(
  3449. id: number,
  3450. path: Pointer<"fz_path">,
  3451. even_odd: number,
  3452. ctm: Pointer<"fz_matrix">,
  3453. colorspace: Pointer<"fz_colorspace">,
  3454. color_n: number,
  3455. color_arr: Pointer<"float">,
  3456. alpha: number
  3457. ): void {
  3458. $libmupdf_device_table.get(id)?.fillPath?.(
  3459. new Path(path),
  3460. !!even_odd,
  3461. fromMatrix(ctm),
  3462. new ColorSpace(colorspace),
  3463. fromColorArray(color_n, color_arr),
  3464. alpha
  3465. )
  3466. },
  3467. clip_path(
  3468. id: number,
  3469. path: Pointer<"fz_path">,
  3470. even_odd: number,
  3471. ctm: Pointer<"fz_matrix">
  3472. ): void {
  3473. $libmupdf_device_table.get(id)?.clipPath?.(
  3474. new Path(path),
  3475. !!even_odd,
  3476. fromMatrix(ctm)
  3477. )
  3478. },
  3479. stroke_path(
  3480. id: number,
  3481. path: Pointer<"fz_path">,
  3482. stroke: Pointer<"fz_stroke_state">,
  3483. ctm: Pointer<"fz_matrix">,
  3484. colorspace: Pointer<"fz_colorspace">,
  3485. color_n: number,
  3486. color_arr: Pointer<"float">,
  3487. alpha: number
  3488. ): void {
  3489. $libmupdf_device_table.get(id)?.strokePath?.(
  3490. new Path(path),
  3491. new StrokeState(stroke),
  3492. fromMatrix(ctm),
  3493. new ColorSpace(colorspace),
  3494. fromColorArray(color_n, color_arr),
  3495. alpha
  3496. )
  3497. },
  3498. clip_stroke_path(
  3499. id: number,
  3500. path: Pointer<"fz_path">,
  3501. stroke: Pointer<"fz_stroke_state">,
  3502. ctm: Pointer<"fz_matrix">
  3503. ): void {
  3504. $libmupdf_device_table.get(id)?.clipStrokePath?.(
  3505. new Path(path),
  3506. new StrokeState(stroke),
  3507. fromMatrix(ctm)
  3508. )
  3509. },
  3510. fill_text(
  3511. id: number,
  3512. text: Pointer<"fz_text">,
  3513. ctm: Pointer<"fz_matrix">,
  3514. colorspace: Pointer<"fz_colorspace">,
  3515. color_n: number,
  3516. color_arr: Pointer<"float">,
  3517. alpha: number
  3518. ): void {
  3519. $libmupdf_device_table.get(id)?.fillText?.(
  3520. new Text(text),
  3521. fromMatrix(ctm),
  3522. new ColorSpace(colorspace),
  3523. fromColorArray(color_n, color_arr),
  3524. alpha
  3525. )
  3526. },
  3527. stroke_text(
  3528. id: number,
  3529. text: Pointer<"fz_text">,
  3530. stroke: Pointer<"fz_stroke_state">,
  3531. ctm: Pointer<"fz_matrix">,
  3532. colorspace: Pointer<"fz_colorspace">,
  3533. color_n: number,
  3534. color_arr: Pointer<"float">,
  3535. alpha: number
  3536. ): void {
  3537. $libmupdf_device_table.get(id)?.strokeText?.(
  3538. new Text(text),
  3539. new StrokeState(stroke),
  3540. fromMatrix(ctm),
  3541. new ColorSpace(colorspace),
  3542. fromColorArray(color_n, color_arr),
  3543. alpha
  3544. )
  3545. },
  3546. clip_text(
  3547. id: number,
  3548. text: Pointer<"fz_text">,
  3549. ctm: Pointer<"fz_matrix">
  3550. ): void {
  3551. $libmupdf_device_table.get(id)?.clipText?.(
  3552. new Text(text),
  3553. fromMatrix(ctm)
  3554. )
  3555. },
  3556. clip_stroke_text(
  3557. id: number,
  3558. text: Pointer<"fz_text">,
  3559. stroke: Pointer<"fz_stroke_state">,
  3560. ctm: Pointer<"fz_matrix">,
  3561. ): void {
  3562. $libmupdf_device_table.get(id)?.clipStrokeText?.(
  3563. new Text(text),
  3564. new StrokeState(stroke),
  3565. fromMatrix(ctm)
  3566. )
  3567. },
  3568. ignore_text(
  3569. id: number,
  3570. text: Pointer<"fz_text">,
  3571. ctm: Pointer<"fz_matrix">
  3572. ): void {
  3573. $libmupdf_device_table.get(id)?.ignoreText?.(
  3574. new Text(text),
  3575. fromMatrix(ctm)
  3576. )
  3577. },
  3578. fill_shade(
  3579. id: number,
  3580. shade: Pointer<"fz_shade">,
  3581. ctm: Pointer<"fz_matrix">,
  3582. alpha: number
  3583. ): void {
  3584. $libmupdf_device_table.get(id)?.fillShade?.(
  3585. new Shade(shade),
  3586. fromMatrix(ctm),
  3587. alpha
  3588. )
  3589. },
  3590. fill_image(
  3591. id: number,
  3592. image: Pointer<"fz_image">,
  3593. ctm: Pointer<"fz_matrix">,
  3594. alpha: number
  3595. ): void {
  3596. $libmupdf_device_table.get(id)?.fillImage?.(
  3597. new Image(image),
  3598. fromMatrix(ctm),
  3599. alpha
  3600. )
  3601. },
  3602. fill_image_mask(
  3603. id: number,
  3604. image: Pointer<"fz_image">,
  3605. ctm: Pointer<"fz_matrix">,
  3606. colorspace: Pointer<"fz_colorspace">,
  3607. color_n: number,
  3608. color_arr: Pointer<"float">,
  3609. alpha: number
  3610. ): void {
  3611. $libmupdf_device_table.get(id)?.fillImageMask?.(
  3612. new Image(image),
  3613. fromMatrix(ctm),
  3614. new ColorSpace(colorspace),
  3615. fromColorArray(color_n, color_arr),
  3616. alpha
  3617. )
  3618. },
  3619. clip_image_mask(
  3620. id: number,
  3621. image: Pointer<"fz_image">,
  3622. ctm: Pointer<"fz_matrix">
  3623. ): void {
  3624. $libmupdf_device_table.get(id)?.clipImageMask?.(
  3625. new Image(image),
  3626. fromMatrix(ctm)
  3627. )
  3628. },
  3629. pop_clip(id: number): void {
  3630. $libmupdf_device_table.get(id)?.popClip?.()
  3631. },
  3632. begin_mask(
  3633. id: number,
  3634. bbox: Pointer<"fz_rect">,
  3635. luminosity: number,
  3636. colorspace: Pointer<"fz_colorspace">,
  3637. color_n: number,
  3638. color_arr: Pointer<"float">
  3639. ): void {
  3640. $libmupdf_device_table.get(id)?.beginMask?.(
  3641. fromRect(bbox),
  3642. !!luminosity,
  3643. new ColorSpace(colorspace),
  3644. fromColorArray(color_n, color_arr)
  3645. )
  3646. },
  3647. begin_group(
  3648. id: number,
  3649. bbox: Pointer<"fz_rect">,
  3650. colorspace: Pointer<"fz_colorspace">,
  3651. isolated: number,
  3652. knockout: number,
  3653. blendmode: number,
  3654. alpha: number
  3655. ): void {
  3656. $libmupdf_device_table.get(id)?.beginGroup?.(
  3657. fromRect(bbox),
  3658. new ColorSpace(colorspace),
  3659. !!isolated,
  3660. !!knockout,
  3661. Device.BLEND_MODES[blendmode] as BlendMode,
  3662. alpha
  3663. )
  3664. },
  3665. begin_tile(
  3666. id: number,
  3667. area: Pointer<"fz_rect">,
  3668. view: Pointer<"fz_rect">,
  3669. xstep: number,
  3670. ystep: number,
  3671. ctm: Pointer<"fz_matrix">,
  3672. tile_id: number
  3673. ): number {
  3674. return $libmupdf_device_table.get(id)?.beginTile?.(
  3675. fromRect(area),
  3676. fromRect(view),
  3677. xstep,
  3678. ystep,
  3679. fromMatrix(ctm),
  3680. tile_id
  3681. ) || 0
  3682. },
  3683. begin_layer(id: number, name: Pointer<"char">): void {
  3684. $libmupdf_device_table.get(id)?.beginLayer?.(
  3685. fromString(name)
  3686. )
  3687. },
  3688. end_mask(id: number): void {
  3689. $libmupdf_device_table.get(id)?.endMask?.()
  3690. },
  3691. end_group(id: number): void {
  3692. $libmupdf_device_table.get(id)?.endGroup?.()
  3693. },
  3694. end_tile(id: number): void {
  3695. $libmupdf_device_table.get(id)?.endTile?.()
  3696. },
  3697. end_layer(id: number): void {
  3698. $libmupdf_device_table.get(id)?.endLayer?.()
  3699. },
  3700. }
  3701. /* default exports */
  3702. export default {
  3703. // const
  3704. Matrix,
  3705. Rect,
  3706. // function
  3707. enableICC,
  3708. disableICC,
  3709. setUserCSS,
  3710. installLoadFontFunction,
  3711. // class
  3712. Buffer,
  3713. ColorSpace,
  3714. Font,
  3715. Image,
  3716. StrokeState,
  3717. Path,
  3718. Text,
  3719. DisplayList,
  3720. Pixmap,
  3721. Shade,
  3722. StructuredText,
  3723. Device,
  3724. DrawDevice,
  3725. DisplayListDevice,
  3726. DocumentWriter,
  3727. Document,
  3728. OutlineIterator,
  3729. Link,
  3730. Page,
  3731. PDFDocument,
  3732. PDFPage,
  3733. PDFObject,
  3734. PDFGraftMap,
  3735. PDFAnnotation,
  3736. PDFWidget,
  3737. Stream,
  3738. // debugging
  3739. memento
  3740. }