Skip to content

Commit

Permalink
add/revise vips_text function
Browse files Browse the repository at this point in the history
  • Loading branch information
steve.3282 committed Feb 24, 2025
1 parent 4f56106 commit f0969a3
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 9 deletions.
6 changes: 6 additions & 0 deletions vips/create.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ int identity(VipsImage **out, int ushort) {
return vips_identity(out, NULL);
}
}

// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text
int text(VipsImage **out, TextOptions *o) {
return vips_text(out, o->Text, "font", o->Font, "width", o->Width, "height", o->Height, "align", o->Align,
"dpi", o->DPI, "rgba", o->RGBA, "justify", o->Justify, "spacing", o->Spacing, "wrap", o->Wrap, NULL);
}
74 changes: 74 additions & 0 deletions vips/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@ package vips

// #include "create.h"
import "C"
import "unsafe"

type TextWrap int

type TextParams struct {
Text string
Font string
Width int
Height int
Alignment Align
DPI int
RGBA bool
Justify bool
Spacing int
Wrap TextWrap
}

type vipsTextOptions struct {
Text *C.char
Font *C.char
Width C.int
Height C.int
DPI C.int
RGBA C.gboolean
Justify C.gboolean
Spacing C.int
Alignment C.VipsAlign
Wrap C.VipsTextWrap
}

// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-xyz
func vipsXYZ(width int, height int) (*C.VipsImage, error) {
Expand Down Expand Up @@ -35,3 +64,48 @@ func vipsIdentity(ushort bool) (*C.VipsImage, error) {

return out, nil
}

// TextWrap enum
const (
TextWrapWord TextWrap = C.VIPS_TEXT_WRAP_WORD
TextWrapChar TextWrap = C.VIPS_TEXT_WRAP_CHAR
TextWrapWordChar TextWrap = C.VIPS_TEXT_WRAP_WORD_CHAR
TextWrapNone TextWrap = C.VIPS_TEXT_WRAP_NONE
)

// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text
func vipsText(params *TextParams) (*C.VipsImage, error) {
var out *C.VipsImage

text := C.CString(params.Text)
defer freeCString(text)

font := C.CString(params.Font)
defer freeCString(font)

opts := vipsTextOptions{
Text: text,
Font: font,
Width: C.int(params.Width),
Height: C.int(params.Height),
DPI: C.int(params.DPI),
Alignment: C.VipsAlign(params.Alignment),
Spacing: C.int(params.Spacing),
Wrap: C.VipsTextWrap(params.Wrap),
}

if params.RGBA {
opts.RGBA = C.TRUE
}

if params.Justify {
opts.Justify = C.TRUE
}

err := C.text(&out, (*C.TextOptions)(unsafe.Pointer(&opts)))
if err != 0 {
return nil, handleImageError(out)
}

return out, nil
}
13 changes: 13 additions & 0 deletions vips/create.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,20 @@
#include <vips/vips.h>
#include <vips/foreign.h>
// clang-format on
typedef struct {
const char *Text;
const char *Font;
int Width;
int Height;
int DPI;
gboolean RGBA;
gboolean Justify;
int Spacing;
VipsAlign Align;
VipsTextWrap Wrap;
} TextOptions;

int xyz(VipsImage **out, int width, int height);
int black(VipsImage **out, int width, int height);
int identity(VipsImage **out, int ushort);
int text(VipsImage **out, TextOptions *o);
6 changes: 6 additions & 0 deletions vips/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,12 @@ func Black(width, height int) (*ImageRef, error) {
return imageRef, err
}

// Text draws the string text to an image.
func Text(params *TextParams) (*ImageRef, error) {
img, err := vipsText(params)
return newImageRef(img, ImageTypeUnknown, ImageTypeUnknown, nil), err
}

func newImageRef(vipsImage *C.VipsImage, currentFormat ImageType, originalFormat ImageType, buf []byte) *ImageRef {
imageRef := &ImageRef{
image: vipsImage,
Expand Down
32 changes: 32 additions & 0 deletions vips/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,38 @@ func TestImageRef_Background(t *testing.T) {
require.Equal(t, 3, len(background))
}

func Test_MakeTextImage(t *testing.T) {
Startup(nil)

textImage, err := Text(&TextParams{
Text: "Test",
Font: "Helvetica",
Width: 10,
Height: 10,
Alignment: AlignLow,
DPI: 72,
Wrap: TextWrapWord,
})
require.NoError(t, err)
require.NotNil(t, textImage)

// pango Image
pangoText := "<span font_desc='Helvetica' font_size='13pt' foreground='black'>Test</span>"
pangoTextImage, err := Text(&TextParams{
Text: pangoText,
Width: 10,
Height: 0,
Alignment: AlignLow,
DPI: 72,
RGBA: true,
Justify: false,
Spacing: 0,
Wrap: TextWrapWord,
})
require.NoError(t, err)
require.NotNil(t, pangoTextImage)
}

// TODO unit tests to cover:
// NewImageFromReader failing test
// NewImageFromFile failing test
Expand Down
6 changes: 0 additions & 6 deletions vips/label.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
#include "label.h"

int text(VipsImage **out, const char *text, const char *font, int width,
int height, VipsAlign align, int dpi) {
return vips_text(out, text, "font", font, "width", width, "height", height,
"align", align, "dpi", dpi, NULL);
}

int label(VipsImage *in, VipsImage **out, LabelOptions *o) {
double ones[3] = {1, 1, 1};
VipsImage *base = vips_image_new();
Expand Down
3 changes: 0 additions & 3 deletions vips/label.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,3 @@ typedef struct {
} LabelOptions;

int label(VipsImage *in, VipsImage **out, LabelOptions *o);

int text(VipsImage **out, const char *text, const char *font, int width,
int height, VipsAlign align, int dpi);

0 comments on commit f0969a3

Please sign in to comment.