Author Topic: Cairo  (Read 3523 times)

TimoVJL

  • Member
  • ***
  • Posts: 477
Re: Cairo
« Reply #15 on: November 21, 2018, 04:38:21 AM »
cairo-windows-1.15.12 have lib files for it, so what was the problem with them?
calling convention is C __cdecl

CONS: PDF text don't work :(
EDIT:
Code: [Select]
// https://cairographics.org/manual/cairo-text.html
// https://www.cairographics.org/tutorial/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

int printf(const char *, ...);
#pragma comment(lib, "msvcrt.lib")
#pragma comment(linker,"/subsystem:console,5.1")
void __cdecl mainCRTStartup(void)
{
int __cdecl main(void);
__declspec(dllimport) void __cdecl exit(int status);
exit(main());
}

typedef void * (__cdecl *CPROC)();

int __cdecl main(void)
{
HMODULE hDll = LoadLibrary("cairo.dll");
if (!hDll) hDll = LoadLibrary("libcairo-2.dll");
if (hDll) {
CPROC cairo_version_string = (CPROC)GetProcAddress(hDll, "cairo_version_string");
CPROC cairo_pdf_surface_create = (CPROC)GetProcAddress(hDll, "cairo_pdf_surface_create");
CPROC cairo_surface_destroy = (CPROC)GetProcAddress(hDll, "cairo_surface_destroy");
CPROC cairo_create = (CPROC)GetProcAddress(hDll, "cairo_create");
CPROC cairo_destroy = (CPROC)GetProcAddress(hDll, "cairo_destroy");
CPROC cairo_show_page = (CPROC)GetProcAddress(hDll, "cairo_show_page");
CPROC cairo_move_to = (CPROC)GetProcAddress(hDll, "cairo_move_to");
//CPROC cairo_line_to = (CPROC)GetProcAddress(hDll, "cairo_line_to");
//CPROC cairo_stroke = (CPROC)GetProcAddress(hDll, "cairo_stroke");
CPROC cairo_select_font_face = (CPROC)GetProcAddress(hDll, "cairo_select_font_face");
CPROC cairo_set_font_size = (CPROC)GetProcAddress(hDll, "cairo_set_font_size");
CPROC cairo_show_text = (CPROC)GetProcAddress(hDll, "cairo_show_text");
if (cairo_version_string && cairo_pdf_surface_create && cairo_create
&& cairo_surface_destroy && cairo_destroy && cairo_show_page
&& cairo_show_text)
{
printf("Version: %s\n", (char*)cairo_version_string());
void *surface = cairo_pdf_surface_create("test.pdf", 504.0, 648.0);
void *cr = cairo_create(surface);
cairo_move_to(cr, 10.0, 50.0);
//cairo_line_to(cr, 30, 25);
//cairo_stroke(cr);
cairo_select_font_face (cr, "Arial", 0, 0);
cairo_set_font_size (cr, 40.0);
cairo_show_text(cr, cairo_version_string());
cairo_show_page(cr);
cairo_destroy(cr);
cairo_surface_destroy(surface);
}
} else printf("error: missing libcairo-2.dll or cairo.dll\n");
return 0;
}
« Last Edit: November 22, 2018, 04:08:11 AM by TimoVJL »
May the source be with you

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9811
  • Assembler is fun ;-)
    • MasmBasic
Re: Cairo
« Reply #16 on: November 21, 2018, 05:05:39 AM »
And here is the full source of my version. The attachment contains also the adapted version that uses biterider's Cairo.inc, which I finally got working - thanks, biterider :icon14:

@Timo: No problem with lib, it works. Biterider's version needs the Cairo.lib, but my version below doesn't; both need Cairo.dll (which raises the question what the added value of a static lib is ... I see that relatively often in packages coming from the Linux world 8))

GuiParas equ "Cairo demo", x550, y20, w160, h180, cblack, b RgbCol(255, 255, 160)
include \masm32\MasmBasic\Res\MbGui.asm        ; pure MasmBasic :P
Dll "\Masm32\Cairo\lib\x86\cairo.dll"          ; suggested path to the Dll (Cairo.lib is not needed)
Declare cairo_version                          ; hit F6 to build; this version works from any folder
Declare cairo_win32_surface_create, C:1
Declare cairo_create, C:1
Declare void cairo_rectangle, C:5
Declare void cairo_set_source_rgba, C:5
Declare void cairo_set_fill_rule, C:2
Declare void cairo_fill, C:1
Declare void cairo_destroy, C:1
Declare void cairo_surface_write_to_png, C:2
Declare void cairo_surface_destroy, C:1
Declare void cairo_status, C:1                 ; for context errors
Declare void cairo_surface_status, C:1         ; for surface errors
Declare void cairo_status_to_string, C:1       ; for all errors
Enum 0:CAIRO_FILL_RULE_WINDING, CAIRO_FILL_RULE_EVEN_ODD       ; for usage, click here
SetGlobals surface, context, ctGuiRefresh, double red, green, blue

Event Timer
  If_ ctGuiRefresh<100 Then mcs inc ctGuiRefresh : GuiRefresh   ; show random colours for a few seconds

Event Paint
  invoke TextOut, PtDC, 9, 5, Str$("Cairo version %i\n", cairo_version()), s$Len
  mov surface, cairo_win32_surface_create(PtDC)
  mov context, cairo_create(eax)
  cairo_rectangle(context, FP8(20.0), FP8(30.0), FP8(100.0), FP8(100.0))
  Rand(0.0, 1.0, red)
  Rand(0.0, 1.0, green)         ; generate random colours
  Rand(0.0, 1.0, blue)
  cairo_set_source_rgba(context, red, green, blue, FP8(0.7))    ; last arg: 0=fully transparent, 1.0=opaque
  cairo_set_fill_rule(context, CAIRO_FILL_RULE_EVEN_ODD)
  cairo_fill(context)
  cairo_destroy(context);
  ; cairo_surface_write_to_png(surface, "test.png")    ; optional: saves client area to disk
  cairo_surface_destroy(surface)
GuiEnd


P.S.: For the old MasmBasic package, the latest version of the Declare macro posted here for HSE is needed; insert an include before Dll...

HSE

  • Member
  • *****
  • Posts: 1148
  • <AMD>< 7-32>
Re: Cairo
« Reply #17 on: November 21, 2018, 05:39:37 AM »
Here are the sources of the demo application.

I think the code is not ObjAsm32 compatible  :biggrin: :biggrin: :biggrin:

Something is silently not working with AsmC (perhaps is a diferent Defined ¿?).



HSE

  • Member
  • *****
  • Posts: 1148
  • <AMD>< 7-32>
Re: Cairo
« Reply #18 on: November 21, 2018, 05:44:31 AM »
P.S.: For the old MasmBasic package, the latest version of the Declare macro posted here for HSE is needed; insert an include before Dll...

And s$Len?  :biggrin:

Vortex

  • Member
  • *****
  • Posts: 2034
Re: Cairo
« Reply #19 on: November 21, 2018, 06:07:16 AM »
It's easy to create the import library with Pelle's library manager Polib :

Code: [Select]
\PellesC\bin\polib.exe  /OUT:cairo.lib /MACHINE:x86 cairo.dll
Thanks Timo for your example. I tested the import library generated by Polib with your example project.

I assume that all the exported functions are following the C calling convention :

Code: [Select]
\PellesC\bin\podump.exe /EXPORTS cairo.dll > cairo_exports.txt
Code: [Select]
      1     0  1006F760  cairo_append_path
              2     1  1006F7D0  cairo_arc
              3     2  1006F890  cairo_arc_negative
              4     3  1006F950  cairo_clip
              5     4  1006F980  cairo_clip_extents
              6     5  1006F9F0  cairo_clip_preserve
              7     6  1006FA20  cairo_close_path
              8     7  1006FA50  cairo_copy_clip_rectangle_list
              9     8  1006FA80  cairo_copy_page
              A     9  1006FAB0  cairo_copy_path
              B     A  1006FAE0  cairo_copy_path_flat
              C     B  1006FB10  cairo_create
              D     C  1006FB80  cairo_curve_to
              E     D  10026660  cairo_debug_reset_static_data
              F     E  1006FC00  cairo_destroy
             10     F  100281B0  cairo_device_acquire
             11    10  10028210  cairo_device_destroy
             12    11  100282A0  cairo_device_finish
.
.

Biterider

  • Member
  • ***
  • Posts: 393
  • ObjAsm32 + ObjAsm64 = ObjAsm
    • ObjAsm
Re: Cairo
« Reply #20 on: November 21, 2018, 07:56:06 AM »
Hi
The .dll and .lib files work fine. No need to rebuild them, but if anyone wants to do it, I attach the .def file.  :idea:

@JJ: you are welcome.  :t

@HSE: it is OA32 but with some additional features I'm working on right now. To avoid naming conflicts, I've added namespaces for objects and interfaces.  In a few weeks, I'll bring the next version showing these improvements.  ;)

Biterider

HSE

  • Member
  • *****
  • Posts: 1148
  • <AMD>< 7-32>
Re: Cairo
« Reply #21 on: November 21, 2018, 08:55:59 AM »
@Biterider:
   
    Perfect now  :t
   
    My mistake, naturally. I was forgotten that I commented background line. You are not using "IncludeAPIs Gdi32" now!
     
    Thanks.


jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9811
  • Assembler is fun ;-)
    • MasmBasic
Gdi+
« Reply #22 on: November 21, 2018, 11:31:19 AM »
include \masm32\MasmBasic\Res\MbGui.asm

MakePen       hPenBez, RgbCol(255, 255, 0, 0), width 4
MakePath      123, Bezier(10:10, 80:40, 40:190, 190:50, 100:170, 180:170, 100:0)

Event Paint
  GuiDraw 123, hPenBez, 10.0, 10.0, 4000, 5000  ; x, y, scaleX, scaleY
GuiEnd


Source & exe attached
« Last Edit: January 27, 2019, 09:49:32 PM by jj2007 »

TimoVJL

  • Member
  • ***
  • Posts: 477
Re: Cairo
« Reply #23 on: November 21, 2018, 09:40:00 PM »
@Timo: No problem with lib, it works. Biterider's version needs the Cairo.lib, but my version below doesn't;
With C, without lib:
http://masm32.com/board/index.php?topic=7534.msg82238#msg82238
May the source be with you

HSE

  • Member
  • *****
  • Posts: 1148
  • <AMD>< 7-32>
Re: Cairo
« Reply #24 on: November 22, 2018, 11:13:09 AM »
I think cairo have problems with text:
Code: [Select]
  invoke cairo_select_font_face, Context, $OfsCStr("Times New Roman"), CAIRO_FONT_SLANT_OBLIQUE, CAIRO_FONT_WEIGHT_NORMAL
invoke cairo_set_font_size , Context, $CReal8(30)
invoke cairo_move_to , Context, $CReal8(30.0),$CReal8(84.0)
invoke cairo_text_path , Context, $OfsCStr("Que lo pario Mendieta...")
invoke cairo_set_source_rgb, Context, $CReal8(0.0),$CReal8(0.0),$CReal8(0.0)
invoke cairo_set_line_width, Context, $CReal8(10.0)
invoke cairo_stroke, Context

invoke cairo_set_font_size , Context,$CReal8(30)
invoke cairo_move_to , Context, $CReal8(30.0),$CReal8(84.0)
invoke cairo_text_path , Context, $OfsCStr("Que lo pario Mendieta...")
invoke cairo_set_source_rgb, Context, $CReal8(200.0),$CReal8(200.0),$CReal8(0.0)
invoke cairo_set_line_width, Context, $CReal8(3.0)
invoke cairo_stroke, Context
   
; Just a line
    invoke cairo_new_path, Context
    invoke cairo_move_to, Context, $CReal8(100.0), $CReal8(100.0)
invoke cairo_line_to, Context, $CReal8(200.0), $CReal8(200.0)
invoke cairo_set_source_rgba, Context, $CReal8(1.0), $CReal8(0.0), $CReal8(0.0), $CReal8(1.0)
    invoke cairo_set_line_width, Context, $CReal8(20.0)
    invoke cairo_stroke, Context

TimoVJL

  • Member
  • ***
  • Posts: 477
Re: Cairo
« Reply #25 on: November 22, 2018, 05:20:26 PM »
Version: 1.14.12 VbCairo stdcall version.
May the source be with you

Biterider

  • Member
  • ***
  • Posts: 393
  • ObjAsm32 + ObjAsm64 = ObjAsm
    • ObjAsm
Re: Cairo
« Reply #26 on: November 22, 2018, 05:55:42 PM »
Hi
@HSE: cooolll  :P   :t


Biterider

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9811
  • Assembler is fun ;-)
    • MasmBasic
Re: Cairo
« Reply #27 on: November 22, 2018, 07:04:12 PM »
Version: 1.14.12 VbCairo stdcall version.

Works like a charm, just replace in my versions
Code: [Select]
Dll "\Masm32\Cairo\lib\x86\cairo.dll" ; suggested path to the Dll (Cairo.lib is not needed)
Declare cairo_version ; hit F6 to build; this version works from any folder
Declare cairo_win32_surface_create, C:1
Declare cairo_create, C:1
...
with
Code: [Select]
Dll "\Masm32\Cairo\lib\x86\vbcairo.dll" ; suggested path to the Dll (Cairo.lib is not needed)
Declare cairo_version ; hit F6 to build; this version works from any folder
Declare cairo_win32_surface_create, 1
Declare cairo_create, 1
...
... i.e. adapt to StdCall instead of C:

The bigger issue is discussed here: Is this worth the effort?
Quote
I have spent the past few months comprehensively perf-testing Cairo against GDI+. In nearly every area where the two libraries overlap (which is 90+% of features), GDI+ is preferable from a performance standpoint. This isn't surprising, given that Cairo's Windows backend largely wraps existing GDI functions ...

etc etc, a long post but worth reading. And it answers my previous question:
I am curious if this lib offers any advantage over plain Gdi or Gdi+

If Cairo offered a lot more than what is possible with Gdi+, then I would pursue that road. But it seems just a wrapper for Gdi+, and a complicated one :(

For comparison:

A Gdi+ rectangle in MasmBasic:
Code: [Select]
  MakePath MyRect, Rect(96:250)                ; before the events
  MakeBrush brushes(0), RgbCol(200, 255, 0, 0)
...
  GuiFill MyRect, brushes(0), 100, 100 ; handle, brush, x, y   ; Event Paint

A Gdi+ rectangle in Cairo (WM_PAINT handler):
Code: [Select]
  mov surface, cairo_win32_surface_create(PtDC)
  mov context, cairo_create(eax)
  cairo_rectangle(context, FP8(20.0), FP8(30.0), FP8(100.0), FP8(100.0))
  cairo_set_source_rgba(context, red, green, blue, FP8(0.7))
  cairo_set_fill_rule(context, CAIRO_FILL_RULE_EVEN_ODD)
  cairo_fill(context)
  cairo_destroy(context);
  cairo_surface_destroy(surface)

Biterider

  • Member
  • ***
  • Posts: 393
  • ObjAsm32 + ObjAsm64 = ObjAsm
    • ObjAsm
Re: Cairo
« Reply #28 on: November 22, 2018, 07:38:58 PM »
Hi JJ
The biggest plus point I see is the platform portability. AFAIK GDI+ is Windows only.
I known, you need much more than cairo to shift to another OS...


My 2 cents.


Biterider

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9811
  • Assembler is fun ;-)
    • MasmBasic
Re: Cairo
« Reply #29 on: November 22, 2018, 08:23:15 PM »
I know, I know... but in my lifetime, I will stick to Windows. It's good that Linux exists, that creates a bit of competition, but honestly, there is not even one Linux; see DistroWatch for the top 300 "distros". Is there a Cairo.lib that works on all of them, as in the Windows world?

What I hate most about portability is that such packages often ship with the Linux equivalent of the whole Windows OS. Gigabytes of extra stuff, slow and bloated. What is the minimum size of a standalone QT executable? 8MB?