Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,28 @@ if (DOXYGEN_FOUND)
qore_wrap_dox(QORE_DOX_SRC ${QORE_DOX_TMPL_SRC})
add_custom_target(QORE_MOD_DOX_FILES DEPENDS ${QORE_DOX_SRC})
add_dependencies(docs-module QORE_MOD_DOX_FILES)

# Two-phase doc build: the initial pass (docs-module) generates cairo.tag with empty
# TAGFILES. User module docs (docs-CairoDataProvider) are then built using cairo.tag,
# generating their own tag files. The final pass (docs-module-final) rebuilds the binary
# module docs with user module tag files in TAGFILES, enabling @ref cross-references
# from the mainpage into user module symbols.

# Suppress unresolved cross-reference warnings in the initial pass
file(APPEND ${CMAKE_BINARY_DIR}/Doxyfile "\n# Suppress warnings for initial pass (no user module TAGFILES available)\nWARN_IF_DOC_ERROR = NO\n")

# Create final-pass Doxyfile from the binary module's Doxyfile with user module tag files
file(COPY_FILE ${CMAKE_BINARY_DIR}/Doxyfile ${CMAKE_BINARY_DIR}/Doxyfile.final)
file(APPEND ${CMAKE_BINARY_DIR}/Doxyfile.final
"\n# Final pass: enable user module cross-references and re-enable doc error warnings\nTAGFILES = ${CMAKE_BINARY_DIR}/CairoDataProvider.tag=../CairoDataProvider/html\nWARN_IF_DOC_ERROR = YES\n")

add_custom_target(docs-module-final
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile.final
COMMAND ${QORE_DOCS_ENV} ${QORE_QDX_COMMAND} --post ${CMAKE_BINARY_DIR}/docs/${module_name}/html ${CMAKE_BINARY_DIR}/docs/${module_name}/html/search
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen (final pass with user module cross-references)"
VERBATIM
)
add_dependencies(docs-module-final docs-CairoDataProvider)
add_dependencies(docs docs-module-final)
endif()
8 changes: 8 additions & 0 deletions docs/footer_template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

<!-- custom footer -->
<div id="footer" style="text-align:center;font-size:80%;margin-left:3em;margin-right:3em;">
<hr/>
<p><a href="http://qore.org/">Qore Programming Language</a></p>
</div>
</body>
</html>
2 changes: 1 addition & 1 deletion qlib/CairoDataProvider/CairoImageDataProvider.qc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public namespace CairoDataProvider {
- @b draw - Draw on existing PNG

@par Data Provider Path
Access via: cairo{}/image/<action>
Access via: @verbatim cairo{}/image/<action> @endverbatim
*/
public class CairoImageDataProvider inherits AbstractDataProvider {
public {
Expand Down
2 changes: 1 addition & 1 deletion qlib/CairoDataProvider/CairoPostScriptDataProvider.qc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public namespace CairoDataProvider {
- @b create - Create PostScript or EPS from draw commands

@par Data Provider Path
Access via: cairo{}/postscript/<action>
Access via: @verbatim cairo{}/postscript/<action> @endverbatim
*/
public class CairoPostScriptDataProvider inherits AbstractDataProvider {
public {
Expand Down
2 changes: 1 addition & 1 deletion qlib/CairoDataProvider/CairoSvgDataProvider.qc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public namespace CairoDataProvider {
- @b to-eps - Convert SVG to EPS (requires librsvg)

@par Data Provider Path
Access via: cairo{}/svg/<action>
Access via: @verbatim cairo{}/svg/<action> @endverbatim
*/
public class CairoSvgDataProvider inherits AbstractDataProvider {
public {
Expand Down
3 changes: 2 additions & 1 deletion src/CairoContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@

QoreCairoContext::QoreCairoContext(QoreCairoSurface* surface, ExceptionSink* xsink) : surface_ref(surface) {
assert(surface);
surface->ref();
// NOTE: caller (QPP-generated code via HARD_QORE_VALUE_OBJ_DATA) already holds a reference
// from getReferencedPrivateData(); we take ownership of that reference here
cr = cairo_create(surface->getSurface());
checkStatus(xsink);
}
Expand Down
28 changes: 28 additions & 0 deletions src/CairoSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ QoreCairoSurface::QoreCairoSurface(const std::string& path, double width, double
xsink->raiseException("CAIRO-ERROR", "surface dimensions must be positive (%.2f x %.2f)", width, height);
return;
}
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_WRITE | QSEC_CREATE, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "SVG surface create")) {
return;
}
surface = cairo_svg_surface_create(path.c_str(), width, height);
checkStatus(xsink);
}
Expand All @@ -59,6 +66,13 @@ QoreCairoSurface::QoreCairoSurface(const std::string& path, double width, double
xsink->raiseException("CAIRO-ERROR", "surface dimensions must be positive (%.2f x %.2f)", width, height);
return;
}
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_WRITE | QSEC_CREATE, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "PostScript surface create")) {
return;
}
surface = cairo_ps_surface_create(path.c_str(), width, height);
checkStatus(xsink);
}
Expand Down Expand Up @@ -87,6 +101,13 @@ QoreCairoSurface::QoreCairoSurface(int width, int height, cairo_format_t format,

// Image surface from PNG file
QoreCairoSurface::QoreCairoSurface(const std::string& path, ExceptionSink* xsink) : type(CST_IMAGE) {
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_READ, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "PNG file load")) {
return;
}
surface = cairo_image_surface_create_from_png(path.c_str());
cairo_status_t status = cairo_surface_status(surface);
if (status != CAIRO_STATUS_SUCCESS) {
Expand Down Expand Up @@ -172,6 +193,13 @@ void QoreCairoSurface::writeToPng(const std::string& path, ExceptionSink* xsink)
xsink->raiseException("CAIRO-ERROR", "writeToPng is only available for image and recording surfaces");
return;
}
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_WRITE | QSEC_CREATE, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "PNG file write")) {
return;
}
cairo_status_t status = cairo_surface_write_to_png(surface, path.c_str());
if (status != CAIRO_STATUS_SUCCESS) {
xsink->raiseException("CAIRO-ERROR", "failed to write PNG to '%s': %s",
Expand Down
7 changes: 7 additions & 0 deletions src/CairoSvgReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
#ifdef HAVE_RSVG

QoreCairoSvgReader::QoreCairoSvgReader(const std::string& path, ExceptionSink* xsink) {
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_READ, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "SVG file load")) {
return;
}
GError* error = nullptr;
GFile* file = g_file_new_for_path(path.c_str());
handle = rsvg_handle_new_from_gfile_sync(file, RSVG_HANDLE_FLAGS_NONE, nullptr, &error);
Expand Down
2 changes: 2 additions & 0 deletions src/QC_CairoContext.qpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,15 @@ nothing CairoContext::setSourceRgba(float r, float g, float b, float a) {
@param y Y offset for the surface origin
*/
nothing CairoContext::setSourceSurface(CairoSurface[QoreCairoSurface] surface, float x, float y) {
ReferenceHolder<QoreCairoSurface> holder(surface, xsink);
ctx->setSourceSurface(surface, x, y, xsink);
}

//! Sets a pattern as the source
/** @param pattern the source pattern
*/
nothing CairoContext::setSource(CairoPattern[QoreCairoPattern] pattern) {
ReferenceHolder<QoreCairoPattern> holder(pattern, xsink);
ctx->setSource(pattern->getPattern(), xsink);
}

Expand Down
8 changes: 8 additions & 0 deletions src/QC_CairoPattern.qpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@
*/
qclass CairoPattern [arg=QoreCairoPattern* pattern; ns=Qore::Cairo];

//! Private constructor - use static factory methods instead
/** @throw CAIRO-ERROR always; CairoPattern objects must be created using static factory methods
*/
private CairoPattern::constructor() {
xsink->raiseException("CAIRO-ERROR", "CairoPattern cannot be constructed directly; use static factory methods");
}

//! Creates a linear gradient pattern
/** @param x0 start point X
@param y0 start point Y
Expand Down Expand Up @@ -102,6 +109,7 @@ static CairoPattern CairoPattern::createRgba(float r, float g, float b, float a)
/** @param surface the source surface
*/
static CairoPattern CairoPattern::createForSurface(CairoSurface[QoreCairoSurface] surface) {
ReferenceHolder<QoreCairoSurface> surface_holder(surface, xsink);
ReferenceHolder<QoreCairoPattern> holder(new QoreCairoPattern(surface, xsink), xsink);
if (*xsink) {
return QoreValue();
Expand Down
7 changes: 7 additions & 0 deletions src/QC_CairoSurface.qpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ hashdecl Qore::Cairo::CairoTextExtents {
*/
qclass CairoSurface [arg=QoreCairoSurface* surface; ns=Qore::Cairo];

//! Private constructor - use static factory methods instead
/** @throw CAIRO-ERROR always; CairoSurface objects must be created using static factory methods
*/
private CairoSurface::constructor() {
xsink->raiseException("CAIRO-ERROR", "CairoSurface cannot be constructed directly; use static factory methods");
}

//! Creates an SVG surface writing to a file
/** @param path output file path
@param width surface width in points
Expand Down
1 change: 1 addition & 0 deletions src/QC_CairoSvgReader.qpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ hash<auto> CairoSvgReader::getDimensions() {
/** @param ctx the target drawing context
*/
nothing CairoSvgReader::renderTo(CairoContext[QoreCairoContext] ctx) {
ReferenceHolder<QoreCairoContext> holder(ctx, xsink);
reader->renderTo(ctx, xsink);
}

Expand Down
1 change: 1 addition & 0 deletions src/cairo-module.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define QORE_CAIRO_MODULE_H

#include <qore/Qore.h>
#include <qore/QoreSandboxManager.h>

extern const TypedHashDecl* hashdeclCairoSurfaceInfo;
extern const TypedHashDecl* hashdeclCairoMatrix;
Expand Down