PDF-Context.h

#ifndef MUPDF_FITZ_CONTEXT_H
#define MUPDF_FITZ_CONTEXT_H

#include “mupdf/fitz/version.h”
#include “mupdf/fitz/system.h”
#include “mupdf/fitz/geometry.h”

typedef struct fz_font_context fz_font_context;
typedef struct fz_colorspace_context fz_colorspace_context;
typedef struct fz_style_context fz_style_context;
typedef struct fz_tuning_context fz_tuning_context;
typedef struct fz_store fz_store;
typedef struct fz_glyph_cache fz_glyph_cache;
typedef struct fz_document_handler_context fz_document_handler_context;
typedef struct fz_output fz_output;
typedef struct fz_context fz_context;

/**
Allocator structure; holds callbacks and private data pointer.
分配器结构; 持有回调和私有数据指针。
*/
typedef struct
{
void *user;
void *(*malloc)(void *, size_t);
void *(*realloc)(void *, void *, size_t);
void (*free)(void *, void *);
} fz_alloc_context;

/**
Exception macro definitions. Just treat these as a black box -
pay no attention to the man behind the curtain.
异常宏定义。
把这些当成一个黑匣子——不要理会窗帘后面的男人。
*/

#define fz_var(var) fz_var_imp((void *)&(var))
#define fz_try(ctx) if (!fz_setjmp(*fz_push_try(ctx))) if (fz_do_try(ctx)) do
#define fz_always(ctx) while (0); if (fz_do_always(ctx)) do
#define fz_catch(ctx) while (0); if (fz_do_catch(ctx))

FZ_NORETURN void fz_vthrow(fz_context *ctx, int errcode, const char *, va_list ap);
FZ_NORETURN void fz_throw(fz_context *ctx, int errcode, const char *, …) FZ_PRINTFLIKE(3,4);
FZ_NORETURN void fz_rethrow(fz_context *ctx);
void fz_vwarn(fz_context *ctx, const char *fmt, va_list ap);
void fz_warn(fz_context *ctx, const char *fmt, …) FZ_PRINTFLIKE(2,3);
const char *fz_caught_message(fz_context *ctx);
int fz_caught(fz_context *ctx);
void fz_rethrow_if(fz_context *ctx, int errcode);

enum
{
FZ_ERROR_NONE = 0,
FZ_ERROR_MEMORY = 1,
FZ_ERROR_GENERIC = 2,
FZ_ERROR_SYNTAX = 3,
FZ_ERROR_MINOR = 4,
FZ_ERROR_TRYLATER = 5,
FZ_ERROR_ABORT = 6,
FZ_ERROR_COUNT
};

/**
Flush any repeated warnings.

Repeated warnings are buffered, counted and eventually printed
along with the number of repetitions. Call fz_flush_warnings
to force printing of the latest buffered warning and the
number of repetitions, for example to make sure that all
warnings are printed before exiting an application.

刷新所有重复警告。

重复警告被缓冲、计数并最终打印
以及重复次数。 调用
fz_flush_warnings
强制打印最新的缓冲警告和
重复次数,例如确保所有
在退出应用程序之前打印警告。
*/
void fz_flush_warnings(fz_context *ctx);

/**
Locking functions

MuPDF is kept deliberately free of any knowledge of particular
threading systems. As such, in order for safe multi-threaded
operation, we rely on callbacks to client provided functions.

A client is expected to provide FZ_LOCK_MAX number of mutexes,
and a function to lock/unlock each of them. These may be
recursive mutexes, but do not have to be.

If a client does not intend to use multiple threads, then it
may pass NULL instead of a lock structure.

In order to avoid deadlocks, we have one simple rule
internally as to how we use locks: We can never take lock n
when we already hold any lock i, where 0 <= i <= n. In order
to verify this, we have some debugging code, that can be
enabled by defining FITZ_DEBUG_LOCKING.
锁定功能

MuPDF
故意不了解任何特定的知识
线程系统。
因此,为了安全的多线程
操作,我们依赖于对客户端提供的函数的回调。

客户端应提供
FZ_LOCK_MAX 个互斥锁,
以及锁定/解锁它们中的每一个的功能。
这些可能是
递归互斥锁,但不是必须的。

如果客户端不打算使用多线程,那么它
可以传递
NULL
而不是锁结构。

为了避免死锁,我们有一个简单的规则
关于我们如何使用锁的内部:我们永远不能获取锁
n
当我们已经持有任何锁 i 时,其中 0 <= i <= n。
为了
为了验证这一点,我们有一些调试代码,可以
通过定义 FITZ_DEBUG_LOCKING 启用。

*/

typedef struct
{
void *user;
void (*lock)(void *user, int lock);
void (*unlock)(void *user, int lock);
} fz_locks_context;

enum {
FZ_LOCK_ALLOC = 0,
FZ_LOCK_FREETYPE,
FZ_LOCK_GLYPHCACHE,
FZ_LOCK_MAX
};

#if defined(MEMENTO) || !defined(NDEBUG)
#define FITZ_DEBUG_LOCKING
#endif

#ifdef FITZ_DEBUG_LOCKING

void fz_assert_lock_held(fz_context *ctx, int lock);
void fz_assert_lock_not_held(fz_context *ctx, int lock);
void fz_lock_debug_lock(fz_context *ctx, int lock);
void fz_lock_debug_unlock(fz_context *ctx, int lock);

#else

#define fz_assert_lock_held(A,B) do { } while (0)
#define fz_assert_lock_not_held(A,B) do { } while (0)
#define fz_lock_debug_lock(A,B) do { } while (0)
#define fz_lock_debug_unlock(A,B) do { } while (0)

#endif /* !FITZ_DEBUG_LOCKING */

/**
Specifies the maximum size in bytes of the resource store in
fz_context. Given as argument to fz_new_context.

FZ_STORE_UNLIMITED: Let resource store grow unbounded.

FZ_STORE_DEFAULT: A reasonable upper bound on the size, for
devices that are not memory constrained.
指定资源存储的最大大小(以字节为单位)
fz_context。
作为 fz_new_context
的参数给出。

FZ_STORE_UNLIMITED:让资源存储无限增长。
FZ_STORE_DEFAULT:合理的大小上限,对于
不受内存限制的设备。

*/
enum {
FZ_STORE_UNLIMITED = 0,
FZ_STORE_DEFAULT = 256 << 20,
};

/**
Allocate context containing global state.

The global state contains an exception stack, resource store,
etc. Most functions in MuPDF take a context argument to be
able to reference the global state. See fz_drop_context for
freeing an allocated context.

alloc: Supply a custom memory allocator through a set of
function pointers. Set to NULL for the standard library
allocator. The context will keep the allocator pointer, so the
data it points to must not be modified or freed during the
lifetime of the context.

locks: Supply a set of locks and functions to lock/unlock
them, intended for multi-threaded applications. Set to NULL
when using MuPDF in a single-threaded applications. The
context will keep the locks pointer, so the data it points to
must not be modified or freed during the lifetime of the
context.

max_store: Maximum size in bytes of the resource store, before
it will start evicting cached resources such as fonts and
images. FZ_STORE_UNLIMITED can be used if a hard limit is not
desired. Use FZ_STORE_DEFAULT to get a reasonable size.

May return NULL.

分配包含全局状态的上下文。
全局状态包含异常堆栈、资源存储、
等。
MuPDF 中的大多数函数都将上下文参数设为
能够引用全局状态。见
fz_drop_context
释放分配的上下文。

alloc:通过一组提供自定义内存分配器
函数指针。为标准库设置为
NULL
分配器。上下文将保留分配器指针,因此
它所指向的数据在此期间不得修改或释放
上下文的生命周期。

locks:提供一组锁和函数来锁定/解锁
它们,用于多线程应用程序。设置为
NULL
在单线程应用程序中使用 MuPDF
时。这
上下文将保留锁指针,因此它指向的数据
在生命周期内不得修改或释放
语境。

max_store:资源存储的最大字节数,之前
它将开始逐出缓存的资源,例如字体和
图片。如果没有硬限制,可以使用
FZ_STORE_UNLIMITED
想要的。使用 FZ_STORE_DEFAULT 获得合理的大小。
可能返回 NULL。

*/
#define fz_new_context(alloc, locks, max_store) fz_new_context_imp(alloc, locks, max_store, FZ_VERSION)

/**
Make a clone of an existing context.

This function is meant to be used in multi-threaded
applications where each thread requires its own context, yet
parts of the global state, for example caching, are shared.

ctx: Context obtained from fz_new_context to make a copy of.
ctx must have had locks and lock/functions setup when created.
The two contexts will share the memory allocator, resource
store, locks and lock/unlock functions. They will each have
their own exception stacks though.

May return NULL.

克隆现有上下文。
此函数旨在用于多线程
每个线程都需要自己的上下文的应用程序,但
部分全局状态,例如缓存,是共享的。
ctx:从
fz_new_context 获得的上下文进行复制。
ctx
在创建时必须有锁和锁/功能设置。
这两个上下文将共享内存分配器、资源
存储、锁定和锁定/解锁功能。
他们每个人都会有
他们自己的异常堆栈。

可能返回NULL。

*/
fz_context *fz_clone_context(fz_context *ctx);

/**
Free a context and its global state.

The context and all of its global state is freed, and any
buffered warnings are flushed (see fz_flush_warnings). If NULL
is passed in nothing will happen.

Must not be called for a context that is being used in an active
fz_try(), fz_always() or fz_catch() block.

释放上下文及其全局状态。
上下文及其所有全局状态被释放,并且任何
缓冲的警告被刷新(参见
fz_flush_warnings)。
如果为空
传入什么都不会发生。

不得为活动中正在使用的上下文调用
fz_try()、fz_always() 或
fz_catch() 块。

*/
void fz_drop_context(fz_context *ctx);

/**
Set the user field in the context.

NULL initially, this field can be set to any opaque value
required by the user. It is copied on clones.
在上下文中设置用户字段。

最初为
NULL,此字段可以设置为任何不透明值
用户要求。 它在克隆上复制。

*/
void fz_set_user_context(fz_context *ctx, void *user);

/**
Read the user field from the context.
从上下文中读取用户字段。
*/
void *fz_user_context(fz_context *ctx);

/**
FIXME: Better not to expose fz_default_error_callback, and
fz_default_warning callback and to allow ‘NULL’ to be used
int fz_set_xxxx_callback to mean “defaults”.

FIXME: Do we need/want functions like
fz_error_callback(ctx, message) to allow callers to inject
stuff into the error/warning streams?
FIXME:最好不要公开
fz_default_error_callback,并且
fz_default_warning 回调并允许使用 'NULL'
int fz_set_xxxx_callback
表示“默认值”。

FIXME:我们是否需要/想要这样的功能
fz_error_callback(ctx, message)
允许调用者注入
东西进入错误/警告流?

/
/
*
The default error callback. Declared publicly just so that the
error callback can be set back to this after it has been
overridden.
默认错误回调。
公开宣布只是为了
错误回调可以在它被设置回这个之后
被覆盖。
*/
void fz_default_error_callback(void *user, const char *message);

/**
The default warning callback. Declared publicly just so that
the warning callback can be set back to this after it has been
overridden.
默认警告回调。
公开宣布只是为了
警告回调可以在它被设置回这个之后
被覆盖。
*/
void fz_default_warning_callback(void *user, const char *message);

/**
Set the error callback. This will be called as part of the
exception handling.

The callback must not throw exceptions!
设置错误回调。
这将被称为
异常处理。

回调不能抛出异常!

*/
void fz_set_error_callback(fz_context *ctx, void (*print)(void *user, const char *message), void *user);

/**
Set the warning callback. This will be called as part of the
exception handling.

The callback must not throw exceptions!
设置警告回调。
这将被称为
异常处理。

回调不能抛出异常!

*/
void fz_set_warning_callback(fz_context *ctx, void (*print)(void *user, const char *message), void *user);

/**
In order to tune MuPDF’s behaviour, certain functions can
(optionally) be provided by callers.
为了调整 MuPDF
的行为,某些功能可以
(可选)由调用者提供。
*/

/**
Given the width and height of an image,
the subsample factor, and the subarea of the image actually
required, the caller can decide whether to decode the whole
image or just a subarea.

arg: The caller supplied opaque argument.

w, h: The width/height of the complete image.

l2factor: The log2 factor for subsampling (i.e. image will be
decoded to (w>>l2factor, h>>l2factor)).

subarea: The actual subarea required for the current operation.
The tuning function is allowed to increase this in size if
required.


给定图像的宽度和高度,
子样本因子,实际上是图像的子区域
需要,调用者可以决定是否解码整个
图像或只是一个子区域。

arg:调用者提供了不透明的参数。

w,
h:完整图像的宽度/高度。

l2factor:二次采样的 log2 因子(即图像将是
解码为 (w>>l2factor,
h>>l2factor))。

subarea:当前操作所需的实际分区。
允许调整功能增加它的大小,如果
必需的。

*/
typedef void (fz_tune_image_decode_fn)(void *arg, int w, int h, int l2factor, fz_irect *subarea);

/**
Given the source width and height of
image, together with the actual required width and height,
decide whether we should use mitchell scaling.

arg: The caller supplied opaque argument.

dst_w, dst_h: The actual width/height required on the target
device.

src_w, src_h: The source width/height of the image.

Return 0 not to use the Mitchell scaler, 1 to use the Mitchell
scaler. All other values reserved.


给定源宽度和高度
图像,连同实际所需的宽度和高度,
决定我们是否应该使用米切尔缩放。

arg:调用者提供了不透明的参数。

dst_w,
dst_h:目标所需的实际宽度/高度
设备。

src_w, src_h:图片的源宽/高。

返回 0 不使用 Mitchell 缩放器,返回 1
使用 Mitchell
定标器。 保留所有其他值。

*/
typedef int (fz_tune_image_scale_fn)(void *arg, int dst_w, int dst_h, int src_w, int src_h);

/**
Set the tuning function to use for
image decode.

image_decode: Function to use.

arg: Opaque argument to be passed to tuning function.

设置调谐功能用于
图像解码。

image_decode:要使用的函数。
arg:要传递给调整函数的不透明参数。

*/
void fz_tune_image_decode(fz_context *ctx, fz_tune_image_decode_fn *image_decode, void *arg);

/**
Set the tuning function to use for
image scaling.

image_scale: Function to use.

arg: Opaque argument to be passed to tuning function.


设置调谐功能用于
图像缩放。

image_scale:要使用的函数。

arg:要传递给调整函数的不透明参数。

*/
void fz_tune_image_scale(fz_context *ctx, fz_tune_image_scale_fn *image_scale, void *arg);

/**
Get the number of bits of antialiasing we are
using (for graphics). Between 0 and 8.
获取我们的抗锯齿位数
使用(用于图形)。 在 0 到 8
之间。
*/
int fz_aa_level(fz_context *ctx);

/**
Set the number of bits of antialiasing we should
use (for both text and graphics).

bits: The number of bits of antialiasing to use (values are
clamped to within the 0 to 8 range).


设置我们应该的抗锯齿位数
使用(用于文本和图形)。

位:要使用的抗锯齿位数(值是
限制在 0 到
8 范围内)。

*/
void fz_set_aa_level(fz_context *ctx, int bits);

/**
Get the number of bits of antialiasing we are
using for text. Between 0 and 8.
获取我们的抗锯齿位数
用于文本。 在 0 到 8 之间。
*/
int fz_text_aa_level(fz_context *ctx);

/**
Set the number of bits of antialiasing we
should use for text.

bits: The number of bits of antialiasing to use (values are
clamped to within the 0 to 8 range).

设置我们的抗锯齿位数
应该用于文本。

位:要使用的抗锯齿位数(值是
限制在 0 到 8
范围内)。
*/
void fz_set_text_aa_level(fz_context *ctx, int bits);

/**
Get the number of bits of antialiasing we are
using for graphics. Between 0 and 8.
获取我们的抗锯齿位数
用于图形。 在 0 到 8 之间。
*/
int fz_graphics_aa_level(fz_context *ctx);

/**
Set the number of bits of antialiasing we
should use for graphics.

bits: The number of bits of antialiasing to use (values are
clamped to within the 0 to 8 range).

设置我们的抗锯齿位数
应该用于图形。

位:要使用的抗锯齿位数(值是
限制在 0 到 8
范围内)。

*/
void fz_set_graphics_aa_level(fz_context *ctx, int bits);

/**
Get the minimum line width to be
used for stroked lines.

min_line_width: The minimum line width to use (in pixels).

获取最小线宽
用于描边线。

min_line_width:要使用的最小线宽(以像素为单位)。

*/
float fz_graphics_min_line_width(fz_context *ctx);

/**
Set the minimum line width to be
used for stroked lines.

min_line_width: The minimum line width to use (in pixels).

设置最小线宽为
用于描边线。

 min_line_width:要使用的最小线宽(以像素为单位)。

*/
void fz_set_graphics_min_line_width(fz_context *ctx, float min_line_width);

/**
Get the user stylesheet source text.
获取用户样式表源文本。
*/
const char *fz_user_css(fz_context *ctx);

/**
Set the user stylesheet source text for use with HTML and EPUB.
设置用于 HTML 和 EPUB的用户样式表源文本。
*/
void fz_set_user_css(fz_context *ctx, const char *text);

/**
Return whether to respect document styles in HTML and EPUB.
返回是否尊重 HTML 和 EPUB 中的文档样式。
*/
int fz_use_document_css(fz_context *ctx);

/**
Toggle whether to respect document styles in HTML and EPUB.
切换是否尊重 HTML 和 EPUB 中的文档样式。
*/
void fz_set_use_document_css(fz_context *ctx, int use);

/**
Enable icc profile based operation.
启用基于 icc 配置文件的操作。
*/
void fz_enable_icc(fz_context *ctx);

/**
Disable icc profile based operation.
禁用基于 icc 配置文件的操作。
*/
void fz_disable_icc(fz_context *ctx);

/**
Memory Allocation and Scavenging:

All calls to MuPDF's allocator functions pass through to the
underlying allocators passed in when the initial context is
created, after locks are taken (using the supplied locking
function) to ensure that only one thread at a time calls
through.

If the underlying allocator fails, MuPDF attempts to make room
for the allocation by evicting elements from the store, then
retrying.

Any call to allocate may then result in several calls to the
underlying allocator, and result in elements that are only
referred to by the store being freed.

内存分配和清理:

所有对 MuPDF
分配器函数的调用都会传递到
 当初始上下文为时传入的底层分配器
 创建,锁定后(使用提供的锁定
 函数)以确保一次只有一个线程调用
 通过。

 如果底层分配器失败,MuPDF
 会尝试腾出空间
 通过从商店中驱逐元素来分配,然后
 重试。

 任何对分配的调用都可能导致多次调用
 底层分配器,并导致元素仅
 被释放的商店引用。

*/

/**
Allocate memory for a structure, clear it, and tag the pointer
for Memento.

Throws exception in the event of failure to allocate.

为结构分配内存,清除它,并标记指针纪念品。

分配失败时抛出异常。
/
#define fz_malloc_struct(CTX, TYPE)
((TYPE
)Memento_label(fz_calloc(CTX, 1, sizeof(TYPE)), #TYPE))

/**
Allocate memory for an array of structures, clear it, and tag
the pointer for Memento.

Throws exception in the event of failure to allocate.

为结构数组分配内存,清除它,并标记Memento 的指针。

分配失败时抛出异常。
/
#define fz_malloc_struct_array(CTX, N, TYPE)
((TYPE
)Memento_label(fz_calloc(CTX, N, sizeof(TYPE)), #TYPE “[]”))

/**
Allocate uninitialized memory for an array of structures, and
tag the pointer for Memento. Does NOT clear the memory!

Throws exception in the event of failure to allocate.

/
#define fz_malloc_array(CTX, COUNT, TYPE)
((TYPE
)Memento_label(fz_malloc(CTX, (COUNT) * sizeof(TYPE)), #TYPE “[]”))
#define fz_realloc_array(CTX, OLD, COUNT, TYPE)
((TYPE*)Memento_label(fz_realloc(CTX, OLD, (COUNT) * sizeof(TYPE)), #TYPE “[]”))

/**
Allocate uninitialized memory of a given size.
Does NOT clear the memory!

May return NULL for size = 0.

Throws exception in the event of failure to allocate.

*/
void *fz_malloc(fz_context *ctx, size_t size);

/**
Allocate array of memory of count entries of size bytes.
Clears the memory to zero.

Throws exception in the event of failure to allocate.

*/
void *fz_calloc(fz_context *ctx, size_t count, size_t size);

/**
Reallocates a block of memory to given size. Existing contents
up to min(old_size,new_size) are maintained. The rest of the
block is uninitialised.

fz_realloc(ctx, NULL, size) behaves like fz_malloc(ctx, size).

fz_realloc(ctx, p, 0); behaves like fz_free(ctx, p).

Throws exception in the event of failure to allocate.

*/
void *fz_realloc(fz_context *ctx, void *p, size_t size);

/**
Free a previously allocated block of memory.

fz_free(ctx, NULL) does nothing.

Never throws exceptions.

*/
void fz_free(fz_context *ctx, void *p);

/**
fz_malloc equivalent that returns NULL rather than throwing
exceptions.
*/
void *fz_malloc_no_throw(fz_context *ctx, size_t size);

/**
fz_calloc equivalent that returns NULL rather than throwing
exceptions.
*/
void *fz_calloc_no_throw(fz_context *ctx, size_t count, size_t size);

/**
fz_realloc equivalent that returns NULL rather than throwing
exceptions.
*/
void *fz_realloc_no_throw(fz_context *ctx, void *p, size_t size);

/**
Portable strdup implementation, using fz allocators.
*/
char *fz_strdup(fz_context *ctx, const char *s);

/**
Fill block with len bytes of pseudo-randomness.
*/
void fz_memrnd(fz_context *ctx, uint8_t *block, int len);

/* Implementation details: subject to change. */

/* Implementations exposed for speed, but considered private. */

void fz_var_imp(void *);
fz_jmp_buf *fz_push_try(fz_context *ctx);
int fz_do_try(fz_context *ctx);
int fz_do_always(fz_context *ctx);
int fz_do_catch(fz_context *ctx);

typedef struct
{
int state, code;
fz_jmp_buf buffer;
} fz_error_stack_slot;

typedef struct
{
fz_error_stack_slot *top;
fz_error_stack_slot stack[256];
int errcode;
void *print_user;
void (*print)(void *user, const char *message);
char message[256];
} fz_error_context;

typedef struct
{
void *print_user;
void (*print)(void *user, const char *message);
int count;
char message[256];
} fz_warn_context;

typedef struct
{
int hscale;
int vscale;
int scale;
int bits;
int text_bits;
float min_line_width;
} fz_aa_context;

struct fz_context
{
void *user;
fz_alloc_context alloc;
fz_locks_context locks;
fz_error_context error;
fz_warn_context warn;

/* unshared contexts */
fz_aa_context aa;
uint16_t seed48[7];

#if FZ_ENABLE_ICC
int icc_enabled;
#endif

/* TODO: should these be unshared? */
fz_document_handler_context *handler;
fz_style_context *style;
fz_tuning_context *tuning;

/* shared contexts */
fz_output *stddbg;
fz_font_context *font;
fz_colorspace_context *colorspace;
fz_store *store;
fz_glyph_cache *glyph_cache;

};

fz_context *fz_new_context_imp(const fz_alloc_context *alloc, const fz_locks_context *locks, size_t max_store, const char *version);

/**
Lock one of the user supplied mutexes.
*/
static inline void
fz_lock(fz_context *ctx, int lock)
{
fz_lock_debug_lock(ctx, lock);
ctx->locks.lock(ctx->locks.user, lock);
}

/**
Unlock one of the user supplied mutexes.
*/
static inline void
fz_unlock(fz_context *ctx, int lock)
{
fz_lock_debug_unlock(ctx, lock);
ctx->locks.unlock(ctx->locks.user, lock);
}

/* Lock-safe reference counting functions */

static inline void *
fz_keep_imp(fz_context *ctx, void *p, int *refs)
{
if §
{
(void)Memento_checkIntPointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_takeRef§;
++*refs;
}
fz_unlock(ctx, FZ_LOCK_ALLOC);
}
return p;
}

static inline void *
fz_keep_imp_locked(fz_context *ctx FZ_UNUSED, void *p, int *refs)
{
if §
{
(void)Memento_checkIntPointerOrNull(refs);
if (*refs > 0)
{
(void)Memento_takeRef§;
++*refs;
}
}
return p;
}

static inline void *
fz_keep_imp8(fz_context *ctx, void *p, int8_t *refs)
{
if §
{
(void)Memento_checkBytePointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_takeRef§;
++*refs;
}
fz_unlock(ctx, FZ_LOCK_ALLOC);
}
return p;
}

static inline void *
fz_keep_imp16(fz_context *ctx, void *p, int16_t *refs)
{
if §
{
(void)Memento_checkShortPointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_takeRef§;
++*refs;
}
fz_unlock(ctx, FZ_LOCK_ALLOC);
}
return p;
}

static inline int
fz_drop_imp(fz_context *ctx, void *p, int *refs)
{
if §
{
int drop;
(void)Memento_checkIntPointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_dropIntRef§;
drop = --*refs == 0;
}
else
drop = 0;
fz_unlock(ctx, FZ_LOCK_ALLOC);
return drop;
}
return 0;
}

static inline int
fz_drop_imp8(fz_context *ctx, void *p, int8_t *refs)
{
if §
{
int drop;
(void)Memento_checkBytePointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_dropByteRef§;
drop = --*refs == 0;
}
else
drop = 0;
fz_unlock(ctx, FZ_LOCK_ALLOC);
return drop;
}
return 0;
}

static inline int
fz_drop_imp16(fz_context *ctx, void *p, int16_t *refs)
{
if §
{
int drop;
(void)Memento_checkShortPointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_dropShortRef§;
drop = --*refs == 0;
}
else
drop = 0;
fz_unlock(ctx, FZ_LOCK_ALLOC);
return drop;
}
return 0;
}

#endif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值