Log of #ghostscript at irc.freenode.net.

 <<<Back 1 day (to 2021/03/15)Fwd 1 day (to 2021/03/17) >>>20210316 
msirabella pdftk dump_data_fields isn't detecting acroform forms fields added with pdfmark and im struggling to add the widgets to the `afields` array (which is empty in the final pdf), am I missing anything obvious?04:07.18 
  The adobe reference says " It is not necessary to explicitly assign the widget annotations to the Fields array; Acrobat does it automatically when the file is", but I'm never getting adobe involved :(04:07.47 
artifexirc-bot <KenSharp> msirabella, pdftk is nothing to do with us. If you are having problems using Ghostscript then you are going to have to supply us with more information, there isn't enough here to answer any questions. Obviously I can't tell you if you are 'missing something' without knowing what you are currently doing.08:11.42 
  <KenSharp> You need to supply us with an example input, and a command line08:11.59 
msirabella I appreciate the response KenSharp! I'm working off of the adobe pdfmark reference found here: https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdfmark_reference.pdf#G9.1500590 , but a stripped down version can be found here: https://pastebin.com/9AQSwrgg08:17.14 
artifexirc-bot <KenSharp> I have the pdfmark reference (all versions), but I don't know what you are doing.08:17.49 
msirabella I'm compiling it with `ps2pdf`, and the output works on both mupdf & chrome, but `pdftk in.pdf dump_data_fields` returns nothing because the `Fields` array in the resulting pdf is empty08:18.54 
artifexirc-bot <KenSharp> Well if MuPDF and chrome read the file correctly, then that sounds like its a pdftk problem08:19.25 
  <KenSharp> You should probably take it up with someone there, at the very least they should be able to tell you waht it is that pdftk doesn't like08:19.49 
msirabella I mean, I can tell you, it doesn't like the empty Fields array, which I suppose isn't a ghostscript problem because adobe says "acrobat fills it on open", but other pdfs with acroforms generated with other means that I can get my hands on fills in the `Fields` array, which is hinted by adobe saying "It will contain entries for each of the widgets defined below"08:23.38 
artifexirc-bot <KenSharp> So you are creating an AcroForm using pdfmark ?08:24.11 
msirabella I am08:24.35 
artifexirc-bot <KenSharp> OK that wasn't clear08:24.50 
  <KenSharp> You ought to be able to add a Fields array to the AcroForm, and in fact if you expect to use it as a form, I think you must do so.08:25.14 
msirabella Apologies if I haven't been clear, thats the understanding I've come to as well08:25.29 
artifexirc-bot <KenSharp> But because the Fields array uses indirect object numbers, this might be challenging. To be honest this is not something I've ever tried to do with Ghostscript08:25.57 
msirabella I suspect readers like poppler & chrome have gone ahead with adobe's assumption of "It is not necessary to explicitly assign the widget annotations to the Fields array" which is why it works without doing that08:26.18 
artifexirc-bot <KenSharp> Well the Widget annotations can appear as Annots in the page dictionary08:27.11 
msirabella yeah, I don't know where the /ANN pdfmark is being handled, but if I can get an object reference to the widgets I'm adding I should be able to /APPEND pdfmark to the `afields` 08:27.24 
artifexirc-bot <KenSharp> Obviously they have to appear **somewhere** in the PDF strucutre 🙂08:27.26 
msirabella Yes, they are, I can check08:27.37 
artifexirc-bot <KenSharp> OK so you are adding them as /ANN pdfmarks, that means the pdfwrite device is adding the result of the /ANN pdfmark to the Annots array of the current page when you execute the pdfmark.08:28.19 
  <KenSharp> There is no mechanism in the Ghostscript PDF itnerpreter to add annotations to an AcroForm, because Ghostscript's PDF itnerpreter and the pdfwrite device do not preserve AcroForms08:28.59 
  <KenSharp> So in order to add the Annotations to the Fields array of the AcroForm, you would have to build the Fields array yourself, manually.08:29.41 
  <KenSharp> And the problem there is that you do not know the object number which pdfwrite assigns to the annotation when it creates it in the PDF file.08:30.05 
msirabella Could I replace the /ANN with something like a create object?08:30.21 
artifexirc-bot <KenSharp> You would have to do something like that, I think, because the only thing you **can** reference is a named object, by name.08:31.03 
  <KenSharp> But that would mean you wouldn't get the annotation resolved as an annotation08:31.17 
  <KenSharp> So I'm doubtful that will work, but its worth a try08:31.28 
  <KenSharp> Yeah I can't see any way of doing this with pdfwrite at present, unless creating a named object works.08:33.32 
  <KenSharp> You should be able to build the Annotations as dictionary objects, using the user-defined object syntax, you will have to add the requisite Type and Subtype keys to the dictionary yourself. You should then be able to reference the named objects to build the Fields array of the AcroForm object.08:36.16 
  <KenSharp> Oh actually the user-defined object stuff says that you can create an Annotation as a user-defined object. You'll have to try that to see if we support it, I''m not sure we do08:37.17 
  <KenSharp> Ah, no, sorry, I'm misreading the spec. They are using ANN as an example08:37.56 
msirabella Yeah KenSharp, thank you very much KenSharp! this seems to be the correct direction. /Type /Annot /OBJ pdfmark is getting me almost there, theres just a pesky /SubType /Text field08:38.32 
artifexirc-bot <KenSharp> Yes I'm afraid you need to add that yourself08:38.52 
  <KenSharp> While this will allow you to create the Fields array, it won't add the annotation to the page dictionary.08:39.18 
  <KenSharp> Maybe you can do that manually too08:39.27 
msirabella I mean, I think its feasable to just do the stuff twice, just glad to know im not missing out on an easier way!08:40.38 
artifexirc-bot <KenSharp> Ah the spec says you can access a page dictionary using PageN where N is a positive integer. Again I'm not certain we support that (pdfwrite does not implement the entire range of pdfmark), but if it does then you could add the /Annots array to the Page dictionary in the same way as you are adding the annotations to the Fields array of the AcroForm08:41.43 
msirabella PageN seems to work as expected08:44.52 
artifexirc-bot <KenSharp> Well I am surprised! 😄08:45.02 
msirabella hopefully ThisPage works too then, that would practically be everything08:45.19 
artifexirc-bot <KenSharp> OK well you shoudl be able to add the same array object as you are creating for the Fields array as the /Annots array of the page dictionary.08:45.27 
  <KenSharp> Sounds like you are pretty close to a solution, good luck!08:45.39 
msirabella thank you! and thank you for your help with this KenSharp!08:46.00 
artifexirc-bot <KenSharp> No problem, hope it works out for you08:46.13 
jhabjan hi, quick question about "gsapi_revision_s" structure (if anyone can help)12:25.11 
  I'm looking what's required to port Ghostscript.NET to .NET Core so it can run on Unix as well as Windows. Looks like on windows gsapi_revision_s has "int" revision data type while on Unix it has "long". Any particular reason for that?12:27.36 
  windows example: https://i.ibb.co/RT71P69/ss-x1-37.png12:29.00 
  unix example: https://i.ibb.co/f0B0nYk/ss-x1-36.png12:29.37 
artifexirc-bot <KenSharp> The source code (/ghostpdl/psi/iapi.h) defines the gsapi_revision_s thus:13:09.26 
  <KenSharp> typedef struct gsapi_revision_s {13:09.27 
  <KenSharp> const char *product;13:09.28 
  <KenSharp> const char *copyright;13:09.30 
  <KenSharp> long revision;13:09.31 
  <KenSharp> long revisiondate;13:09.32 
  <KenSharp> } gsapi_revision_t;13:09.33 
  <KenSharp> So clearly on Windows the compiler has a 'long' defined as a 32-bit data type and on Linux the compiler has it as a 64 bit data type.13:09.51 
jhabjan Thanks, I get that. So, as far as I can see the only way to handle this is to call gsapi_revision with 32-bit 'revision' and 'revisiondate' first and check if the result is 0. If it is, then I can assume that 'long' is 32-bit. If it returns anything else then 0 that's going to be required structure size which I can compare to a structure with13:58.10 
  'revision' and 'revisiondate' as 64-bit data types and make another call to gsapi_revision with required structure... :-) 13:58.11 
artifexirc-bot <KenSharp> The definition of long should be the same for the compiler you are using to build the executable linked to Ghostscript I'd have thought. But if you are using something other than C then I suppose that could be a problem. We do rather tend to assume a C interface.13:59.47 
  <KenSharp> Let me go and talk to someone else for a minute14:00.08 
  <KenSharp> Looks like he's at lunch, I'll talk to him when he's back and then back here14:00.47 
jhabjan .NET library is portable and built for Any CPU14:01.02 
  no worries14:01.14 
artifexirc-bot <KenSharp> Yes, and so is Ghostscript, but it assumes a C interface. Presumably if you've built using a C compiler on Linux its definition of 'long' will be the same as the one used for building Ghostscript on Linux. And so on for Windows.14:01.46 
  <KenSharp> But the fact that 'long' is defined differently on different C compilers makes me think we should move away from it. But I want to discuss it14:02.28 
  <KenSharp> And it may be too late to get such a change in the current release14:02.38 
jhabjan That's fine. Windows version of Ghostscript library I'm testing with is latest 64bit one built / released by Artifex. The Linux one I compiled used default settings.. I just run ./configure and make so...14:07.31 
  Just to make it more clear, what I wanted to say by "built for Any CPU" is when you compile .NET library as Any CPU, it will work (you can use it) in any environment (32 bit or 64 bit). You don't need to compile it specifically for 32 bit platform or 64 bit platform, Windows or Unix. It's cross-platform..14:17.38 
artifexirc-bot <KenSharp> Doesn't really affect us.14:18.16 
jhabjan that's right14:18.23 
  but it makes implementation in languages other then C a bit messier :-)14:20.44 
artifexirc-bot <Robin_Watts> Right, so you should have the C interface layer call the API using "long" and that'll work anywhere.14:21.42 
  <KenSharp> That is rather my point, while it works for C, because the definition of 'long' will be the same, we shouldn't use a data type which is note well specified. We have 32 and 64 bit internal data types, we should use one of those. But this is not my area of teh code which is why I want to talk it through with the owner14:21.42 
  <KenSharp> Oh Hi @Robin_Watts14:21.47 
  <Robin_Watts> You should pass it back in .net using whatever 64bit datatype is.14:21.58 
  <Robin_Watts> Then it'll work everywhere.14:22.06 
  <KenSharp> Yeah but on Windows long is 32-bit14:22.24 
  <KenSharp> So a .NET application can't know.14:22.40 
  <KenSharp> If you were loading the DLL with something other than a C latyer, would you need a 32 or 64 bit data type ?14:23.02 
  <KenSharp> I guess the export definition file should tell us14:23.20 
jhabjan @Robin_Watts, in .NET long is 64-bit, int is 32-bit, Ghostscript library for Windows (Artifex release) is compiled with long as 32-bit and that's where confusion comes..14:28.16 
artifexirc-bot <Robin_Watts> yes, I understand the problem.14:28.40 
  <Robin_Watts> Personally, I *never* use the long type for this reason, but it's something we're stuck with.14:29.06 
  <Robin_Watts> Marshall.sizeOf(long) ?14:30.28 
  <Robin_Watts> That's supposed to get you the size of the unmanaged type 'long' in bytes, which should tell you how to call it ?14:30.56 
jhabjan it does, it says it's 64-bit.. but ghostscript api expects 32-bit14:31.20 
artifexirc-bot <KenSharp> Yeah I think the Marshall.sizeOf tells you the size of the object in .NET14:33.21 
  <KenSharp> Not in C14:33.24 
jhabjan that's right14:33.50 
artifexirc-bot <Robin_Watts> I thought, that C was 'unmanaged' code, and .net was 'managed' code ?14:34.28 
  <KenSharp> I must admit I'm not sure, though 'unmanaged' I thougth just meant 'not in .NET'14:35.14 
  <KenSharp> So I haven't got a good idea, I know very little about .NET you'd need @mvrhel for that I think14:35.41 
jhabjan when calling unmanaged code from managed code you need to specify exact data type14:35.42 
artifexirc-bot <Robin_Watts> https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.sizeof?view=net-5.014:35.45 
  <Robin_Watts> They have an example there where they convert a struct from managed to unmanaged, and back again.14:36.14 
  <KenSharp> Well SizeOf(Object) is already deprecated 😦14:36.17 
  <Robin_Watts> and they are at pains to say that the size can change.14:36.29 
jhabjan you can use sizeof(type)14:36.33 
  "Marshal.SizeOf" takes object instance as parameter while "sizeof" takes type14:37.45 
artifexirc-bot <KenSharp> The docs there say Marshall.SizeOf can take a type14:38.09 
  <KenSharp> SizeOf<T> ?14:39.09 
  <Robin_Watts> jhaban: Try a simple .net program that prints SizeOf(long) and run it on windows and linux and see if you get different answers.14:40.27 
jhabjan https://i.ibb.co/rsxm2MX/ss-x1-39.png14:40.37 
artifexirc-bot <Robin_Watts> That's running on linux, right?14:41.16 
  <Robin_Watts> And that's calling sizeof not SizeOf.14:41.35 
  <Robin_Watts> AIUI, sizeof works in managed types, SizeOf in unmanaged types.14:41.54 
jhabjan that was Windows14:41.56 
  and aboce is Linux14:42.04 
artifexirc-bot <Robin_Watts> Right, because you are using sizeof, that's what I'd expect.14:42.14 
jhabjan here is both, sizeof and Marshal.SizeOf14:44.03 
  windows: https://i.ibb.co/48S1Jh9/ss-x1-41.png14:44.06 
  linux: https://i.ibb.co/v1s36cK/ss-x1-42.png14:45.10 
artifexirc-bot <Robin_Watts> Urgh.14:46.25 
  <Robin_Watts> Well, you're screwed then 😦14:46.39 
  <Robin_Watts> I can't believe .net doesn't have a way of coping with this.14:46.49 
jhabjan .net doesn't know how ghostscript library is compiled14:46.51 
  one solution would be expose one more api method.. something like "get data type mappings"14:47.18 
  Uploaded file: https://uploads.kiwiirc.com/files/0aa15159b68bcf1e69e33c6be5df458b/pasted.txt14:48.14 
  other workaround would be what I mentioned earlier: First call gsapi_revision with 32-bit 'revision' and 'revisiondate' first and check if the result is 0. If it is, then I can assume that 'long' is 32-bit. If it returns anything else then 0 that's going to be required structure size which I can compare to a structure with 'revision' and14:48.41 
  'revisiondate' as 64-bit data types and make another call to gsapi_revision with required structure14:48.42 
artifexirc-bot <Robin_Watts> Yes, I think that should work.14:49.07 
  <Robin_Watts> Oh.14:49.31 
  <Robin_Watts> Call gsapi_revision(NULL, 0); and it'll return you the structure size required.14:49.52 
jhabjan yep, that would work14:50.38 
  I've checked other api structures and it looks like long is used only in this one14:51.37 
  so that would do14:51.40 
  anyway, thanks, just wanted to point out this issue I run into (for other languages then C)14:53.46 
artifexirc-bot <Robin_Watts> jhabjan: Thanks. Like I say, there isn't anything we can do about it. Any other structure in the code, but not this one 😦14:57.03 
jhabjan no worries14:57.59 
 <<<Back 1 day (to 2021/03/15)Forward 1 day (to 2021/03/17)>>> 
ghostscript.com #mupdf