Files
scummvm-cursorfix/engines/sword25/gfx/image/art.h
2026-02-02 04:50:13 +01:00

216 lines
5.3 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* This code is based on Libart_LGPL - library of basic graphic primitives
*
* Copyright (c) 1998 Raph Levien
*
* Licensed under GNU LGPL v2
*
*/
/* Simple macros to set up storage allocation and basic types for libart
functions. */
#ifndef __ART_H__
#define __ART_H__
#include "common/scummsys.h"
namespace Sword25 {
/* These aren't, strictly speaking, configuration macros, but they're
damn handy to have around, and may be worth playing with for
debugging. */
#define art_new(type, n) ((type *)malloc ((n) * sizeof(type)))
#define art_renew(p, type, n) ((type *)realloc (p, (n) * sizeof(type)))
/* This one must be used carefully - in particular, p and max should
be variables. They can also be pstruct->el lvalues. */
#define art_expand(p, type, max) \
do { \
if (max) {\
type *tmp = art_renew(p, type, max <<= 1); \
if (!tmp) error("Cannot reallocate memory for art data"); \
p = tmp; \
} else { \
max = 1; \
p = art_new(type, 1); \
if (!p) error("Cannot allocate memory for art data"); \
} \
} while (0)
struct ArtDRect {
/*< public >*/
double x0, y0, x1, y1;
};
struct ArtPoint {
/*< public >*/
double x, y;
};
/* Basic data structures and constructors for sorted vector paths */
struct ArtSVPSeg {
int n_points;
int dir; /* == 0 for "up", 1 for "down" */
ArtDRect bbox;
ArtPoint *points;
};
struct ArtSVP {
int n_segs;
ArtSVPSeg segs[1];
};
void art_svp_free(ArtSVP *svp);
/* Basic data structures and constructors for bezier paths */
enum ArtPathcode {
ART_MOVETO,
ART_MOVETO_OPEN,
ART_CURVETO,
ART_LINETO,
ART_END
};
struct ArtBpath {
/*< public >*/
ArtPathcode code;
double x1;
double y1;
double x2;
double y2;
double x3;
double y3;
};
/* Basic data structures and constructors for simple vector paths */
/* CURVETO is not allowed! */
struct ArtVpath {
ArtPathcode code;
double x;
double y;
};
/* Some of the functions need to go into their own modules */
void art_vpath_add_point(ArtVpath **p_vpath, int *pn_points, int *pn_points_max,
ArtPathcode code, double x, double y);
ArtVpath *art_bez_path_to_vec(const ArtBpath *bez, double flatness);
/* The funky new SVP intersector. */
#ifndef ART_WIND_RULE_DEFINED
#define ART_WIND_RULE_DEFINED
enum ArtWindRule {
ART_WIND_RULE_NONZERO,
ART_WIND_RULE_INTERSECT,
ART_WIND_RULE_ODDEVEN,
ART_WIND_RULE_POSITIVE
};
#endif
struct ArtSvpWriter {
int (*add_segment)(ArtSvpWriter *self, int wind_left, int delta_wind,
double x, double y);
void (*add_point)(ArtSvpWriter *self, int seg_id, double x, double y);
void (*close_segment)(ArtSvpWriter *self, int seg_id);
};
ArtSvpWriter *art_svp_writer_rewind_new(ArtWindRule rule);
ArtSVP *art_svp_writer_rewind_reap(ArtSvpWriter *self);
int art_svp_seg_compare(const void *s1, const void *s2);
void art_svp_intersector(const ArtSVP *in, ArtSvpWriter *out);
/* Sort vector paths into sorted vector paths. */
ArtSVP *art_svp_from_vpath(ArtVpath *vpath);
/* Sort vector paths into sorted vector paths. */
enum ArtPathStrokeJoinType {
ART_PATH_STROKE_JOIN_MITER,
ART_PATH_STROKE_JOIN_ROUND,
ART_PATH_STROKE_JOIN_BEVEL
};
enum ArtPathStrokeCapType {
ART_PATH_STROKE_CAP_BUTT,
ART_PATH_STROKE_CAP_ROUND,
ART_PATH_STROKE_CAP_SQUARE
};
ArtSVP *art_svp_vpath_stroke(ArtVpath *vpath,
ArtPathStrokeJoinType join,
ArtPathStrokeCapType cap,
double line_width,
double miter_limit,
double flatness);
/* This version may have winding numbers exceeding 1. */
ArtVpath *art_svp_vpath_stroke_raw(ArtVpath *vpath,
ArtPathStrokeJoinType join,
ArtPathStrokeCapType cap,
double line_width,
double miter_limit,
double flatness);
/* The spiffy antialiased renderer for sorted vector paths. */
struct ArtSVPRenderAAStep {
int x;
int delta; /* stored with 16 fractional bits */
};
struct ArtSVPRenderAAIter;
ArtSVPRenderAAIter *art_svp_render_aa_iter(const ArtSVP *svp,
int x0, int y0, int x1, int y1);
void art_svp_render_aa_iter_step(ArtSVPRenderAAIter *iter, int *p_start,
ArtSVPRenderAAStep **p_steps, int *p_n_steps);
void art_svp_render_aa_iter_done(ArtSVPRenderAAIter *iter);
void art_svp_render_aa(const ArtSVP *svp,
int x0, int y0, int x1, int y1,
void (*callback)(void *callback_data,
int y,
int start,
ArtSVPRenderAAStep *steps, int n_steps),
void *callback_data);
} // End of namespace Sword25
#endif /* __ART_H__ */