[erlang-questions] ErlGuten

Theepan vasdeveloper@REDACTED
Tue Sep 25 20:45:13 CEST 2018


Hi Sean,

I used GraphicsMagic to remove the alpha channel before passing onto
ErlGuten. It ensures that the code not taking that inefficient path. It
works very well.

I hope ErlGuten needs to be improved for image embedding support and
performance using port. Also when the alpha channel is removed, eg_pdg
gen_server can be made to work for parallel PDF generation by removing the
local name registration.

Best,
Theepan



On Tue, Sep 25, 2018 at 7:50 PM Sean Hinde <sean.hinde@REDACTED> wrote:

> I hit the same issue. I guess you are using one of the versions with lots
> of lists:nth.
>
> Following find my patch on the version I was using.
>
> You can find my branch at:
>
> https://github.com/proactively/erlguten/tree/png-performance
>
> No time right now to make nice pull requests - I will eventually
>
> ===============================================
>
> diff --git a/src/eg_pdf_image.erl b/src/eg_pdf_image.erl
> index 1a97e0b..817f1b8 100644
> --- a/src/eg_pdf_image.erl
> +++ b/src/eg_pdf_image.erl
> @@ -431,11 +431,11 @@ extractScanLines(Width,Decompressed) ->
>
>  extractLine(ScanLines,Width,<< >>) ->
>    AlmostDone = lists:reverse(ScanLines),
> -  [ {0, string:chars(0,Width-1)} | AlmostDone];
> +  [ {0, list_to_binary(string:chars(0,Width-1))} | AlmostDone];
>  extractLine(ScanLines,Width,Image) ->
>    LineSize = Width - 1,
>    << Method:8, Line:LineSize/binary-unit:8, Rest/binary>> = Image,
> -  extractLine([{Method,  binary_to_list(Line) } | ScanLines ], Width,
> Rest).
> +  extractLine([{Method,  Line} | ScanLines ], Width, Rest).
>
>  %% @doc Remove the filter on all the bytes in the scan lines.
>
> @@ -448,19 +448,26 @@ processLine([{_Method, _Line1}], _Iter, _Offset,
> Results)->
>     A = lists:flatten( lists:reverse(Results) ),
>     list_to_binary( A );
>  processLine([{_, Line1},{Method, Line2} | Remainder], Iter, Offset,
> Results) ->
> -  {ok, Unfiltered} = defilter(Method, Line1,
> Line2,Offset,length(Line1),Iter),
> +  {ok, Unfiltered} = defilter(Method, Line1,
> Line2,Offset,size(Line1),Iter),
>    processLine([{Method, Unfiltered } | Remainder], Iter, Offset,
> [Unfiltered | Results] ).
>
>  %% @doc Taking two lines of stream defilter the 2nd with the previously
> defiltered 1st line.
>
>  defilter(Method, Line1, Line2, Offset, Width, Iter) when Iter =< Width ->
>    NewVal = case Iter =< Offset of
> -    true ->  filter(lists:nth(Iter,Line2), 0, lists:nth(Iter,Line1), 0,
> Method);
> -    false ->  filter(lists:nth(Iter,Line2), lists:nth(Iter-Offset,Line2),
> lists:nth(Iter,Line1), lists:nth(Iter-Offset,Line1), Method)
> +    true ->  filter(binary:at(Line2, Iter - 1), 0,
> +                    binary:at(Line1, Iter - 1), 0, Method);
> +    false ->  filter(binary:at(Line2, Iter - 1),
> +                     binary:at(Line2, Iter - Offset - 1),
> +                     binary:at(Line1, Iter - 1),
> +                     binary:at(Line1, Iter - Offset - 1), Method)
>      end,
>      L2 = case Iter == Width of
> -      true -> lists:flatten([lists:sublist(Line2,Iter - 1),NewVal]);
> -      false -> lists:flatten([lists:sublist(Line2,Iter -
> 1),NewVal,lists:nthtail(Iter, Line2)])
> +      true -> Start = binary:part(Line2, 0, Iter - 1),
> +              <<Start/binary, NewVal>>;
> +      false -> Start = binary:part(Line2, 0, Iter - 1),
> +               End = binary:part(Line2, Iter, size(Line2) - Iter),
> +               <<Start/binary, NewVal, End/binary>>
>      end,
>      defilter(Method, Line1, L2 ,Offset, Width, Iter+1);
>  defilter(_Method, _Line1, Line2, _Offset, _Width, _Iter) ->
> @@ -513,8 +520,7 @@ inflate_stream(Data) ->
>    Decompressed = zlib:inflate(Z, Data),
>    ok = zlib:inflateEnd(Z),
>    zlib:close(Z),
> -  F = fun(A, B) -> <<A/binary, B/binary>> end,
> -  MergedBinaries = lists:foldr(F, <<>>, Decompressed),
> +  MergedBinaries = iolist_to_binary(Decompressed),
>    {ok,MergedBinaries}.
>
>  %% @doc Compress a bit stream using the zlib/deflate algorithm
>
> ===============================================
>
> On 25 Sep 2018, at 01:15, Theepan <vasdeveloper@REDACTED> wrote:
>
> Thanks Lloyd for your detailed explanation on what has been done, and your
> vision for the library. However we are already using ErlGuten in one of our
> production systems, and the issues is mainly with the images.
>
> I will definitely keep an eye on the development of erlpress_core in the
> future, as you seem enthusiastic about making it a lively library.
>
> The issues we have are:
>
> ** When some JPEG image is embedded into the PDF, it turns out dark in the
> generated PDF file
> ** When some PNG file is embedded, it takes too long (unto 5 minutes) to
> generate the PDF file. Debugging shows that the delay is on defilter(
> Method, Line1, Line2, Offset, Width, Iter) of eg_pdf_image module.
>
> Did you come acrsoss this?
>
> Best,
> Theepan
>
>
>
>
>
> On Tue, Sep 25, 2018 at 2:56 AM <lloyd@REDACTED> wrote:
>
>> Hi Theepan,
>>
>> 1. If you look at ErlGuten source, you'll see that function documentation
>> is fairly minimal and many parameters have single character names with
>> little to no documentation. This makes maintenance and revision very
>> difficult. I consider the core ErlGuten modules diamonds-in-the-rough.
>>
>> I also found the high-level page make-up functions provided by Hugh and
>> Carl limited with respect to professional page make-up and, to me at least,
>> a bit confusing.
>>
>> But erlpress_core owes a deep debt and much gratitude to the ErlGuten
>> lineage.
>>
>> erlpress_core is based on Joe's font-handling, justification, and XML
>> parsing code with few if any changes. But it provides map structures to
>> represent nearly all of the PDF objects represented in eg_pdf_op.erl. These
>> map structures incorporate many default parameters so generating PDF
>> documents is syntactically simple and consistent without sacrificing
>> expressive flexibility. You can easily customize display by instantiating
>> map parameters with your own values.
>>
>> You can see most of the PDF objects currently supported by erlpress_core,
>> including boxed text, justification options, and various line and text
>> objects, demonstrated in ep_show_n_tell.pdf and the source in
>> ep_show_n_tell.erl.
>>
>> If you look at the map definitions of the various PDF objects, you'll see
>> how to customize display.
>>
>> At some point if would be good to re-write the base Erlguten modules with
>> more explicit function and parameter documentation, but I'm not up to that
>> at this point. But, anyone looking for a challenge is free to jump in.
>>
>> I'm currently working on tables and text flow across pages (think reports
>> and book chapters). Hope to deliver these features plus much code polishing
>> in the next release coming "real soon now."
>>
>> High on my wish/to-do list are:
>>
>> -- Easy-to_use page-grid design functions
>> -- Imposition (printing multiple page impressions on a single sheet of
>> paper stock)
>> -- Articles and beads (think text jumping across  columns and pages)
>> -- Easy-to-use and expressive page make-up functions
>> -- Example templates for various print formats
>> -- Markdown input
>> -- Support of TTF and OTF fonts
>>
>> Joe Armstrong expressed the following goal when he first announced
>> ErlGuten:
>>
>> "Better than TeX."
>>
>> That's a tall order, yet to be realized. My hope is that erlpress will
>> move the ball further down the field.
>>
>> 2. I haven't done anything with image formats beyond what you'll find in
>> eg_pdf_image.erl. I'd welcome work in that direction.
>>
>> 3. erlpress_core is still at Version 0.01. It's just out. I'm working
>> toward sufficient functionality and stability to support a web application
>> that we have currently under development.
>>
>> 4. I developed erlpress_core on Erlang/OTP 19. It does require support
>> for maps.
>>
>> I see the erlpress_core library as a valuable library for embedding PDF
>> generation into Erlang applications and as the basis for many exciting
>> Erlang-based print production tools.
>>
>> So, Treepan, I appreciate your interest and would welcome your
>> involvement in testing and feature development.
>>
>> I would jump for joy if some Erlang guru were to step forward take on the
>> TTF/OTF support issue. I've done some research and have a few ideas on how
>> expanded font support might be accomplished, but have too little time over
>> the next several months to dig into it.
>>
>> Incidentally, in my previous post my iPad decided it was smarter than me
>> and erroneously corrected my GitHUb address.it should be
>> writersglen/erlPress_core.
>>
>> My intention is to bag the camel case in my next release with luck in a
>> week or two so it should look like writersglen/erlpress_core.
>>
>> All the best,
>>
>> Lloyd
>>
>>
>> -----Original Message-----
>> From: "Theepan" <vasdeveloper@REDACTED>
>> Sent: Monday, September 24, 2018 3:59pm
>> To: lloyd@REDACTED
>> Cc: "Erlang Questions Mailing List" <erlang-questions@REDACTED>, "Joe
>> Armstrong" <erlang@REDACTED>
>> Subject: Re: [erlang-questions] ErlGuten
>>
>> Hi Lloyd,
>>
>> Thank you for your response. I have some quick clarifications --
>>
>> * What are the major improvements made on the source ErlGuten? Did you
>> improve support to different image formats? Any critical bugs fixed?
>> * Is erlPress_core used in commercial applications, specifically of high
>> throughput types?
>> * What is the minimum erlang/OTP version required?
>>
>> Best,
>> Theepan
>>
>>
>>
>>
>>
>>
>> On Mon, Sep 24, 2018 at 6:36 AM Lloyd R. Prentice <lloyd@REDACTED>
>> wrote:
>>
>> > Hi Thepan,
>> >
>> > I’ve undertaken a major revision of ErlGuten called erlPress_core—
>> > announced it on Erlang questions several weeks ago.  It’s available from
>> > GitHub as Writersglen/erlPress_core. I think you’ll find it much more
>> > accessible than the ErlGutens.
>> >
>> > I’ve since been polishing up the code and adding a few new features.
>> After
>> > the launch I learned that camel case is not conventional usage when it
>> > comes to the names of Erlang applications and libraries. So I plan to
>> > release the updated version as erlpress_core. With smooth sailing I
>> hope to
>> > release sometime this week or next.
>> >
>> > All the best,
>> >
>> > Lloyd
>> >
>> > Sent from my iPad
>> >
>> > On Sep 23, 2018, at 8:30 PM, Theepan <vasdeveloper@REDACTED> wrote:
>> >
>> >
>> > Hi Team,
>> >
>> > I see many forks of ErlGuten. Which one is the latest, most stable and
>> > widely used?
>> >
>> > https://github.com/richcarl/erlguten
>> > https://github.com/CarlWright/NGerlguten
>> > https://github.com/hwatkins/erlguten/commits/master
>> >
>> > Best,
>> > Theepan
>> >
>> >
>> > _______________________________________________
>> > erlang-questions mailing list
>> > erlang-questions@REDACTED
>> > http://erlang.org/mailman/listinfo/erlang-questions
>> >
>> >
>>
>>
>> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20180926/c7b65495/attachment.htm>


More information about the erlang-questions mailing list