base_context.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include "fitz-internal.h"
  2. void
  3. fz_free_context(fz_context *ctx)
  4. {
  5. if (!ctx)
  6. return;
  7. /* Other finalisation calls go here (in reverse order) */
  8. fz_drop_glyph_cache_context(ctx);
  9. fz_drop_store_context(ctx);
  10. fz_free_aa_context(ctx);
  11. fz_drop_font_context(ctx);
  12. if (ctx->warn)
  13. {
  14. fz_flush_warnings(ctx);
  15. fz_free(ctx, ctx->warn);
  16. }
  17. if (ctx->error)
  18. {
  19. assert(ctx->error->top == -1);
  20. fz_free(ctx, ctx->error);
  21. }
  22. /* Free the context itself */
  23. ctx->alloc->free(ctx->alloc->user, ctx);
  24. }
  25. /* Allocate new context structure, and initialise allocator, and sections
  26. * that aren't shared between contexts.
  27. */
  28. static fz_context *
  29. new_context_phase1(fz_alloc_context *alloc, fz_locks_context *locks)
  30. {
  31. fz_context *ctx;
  32. ctx = alloc->malloc(alloc->user, sizeof(fz_context));
  33. if (!ctx)
  34. return NULL;
  35. memset(ctx, 0, sizeof *ctx);
  36. ctx->alloc = alloc;
  37. ctx->locks = locks;
  38. ctx->glyph_cache = NULL;
  39. ctx->error = fz_malloc_no_throw(ctx, sizeof(fz_error_context));
  40. if (!ctx->error)
  41. goto cleanup;
  42. ctx->error->top = -1;
  43. ctx->error->message[0] = 0;
  44. ctx->warn = fz_malloc_no_throw(ctx, sizeof(fz_warn_context));
  45. if (!ctx->warn)
  46. goto cleanup;
  47. ctx->warn->message[0] = 0;
  48. ctx->warn->count = 0;
  49. /* New initialisation calls for context entries go here */
  50. fz_try(ctx)
  51. {
  52. fz_new_aa_context(ctx);
  53. }
  54. fz_catch(ctx)
  55. {
  56. goto cleanup;
  57. }
  58. return ctx;
  59. cleanup:
  60. fprintf(stderr, "cannot create context (phase 1)\n");
  61. fz_free_context(ctx);
  62. return NULL;
  63. }
  64. fz_context *
  65. fz_new_context(fz_alloc_context *alloc, fz_locks_context *locks, unsigned int max_store)
  66. {
  67. fz_context *ctx;
  68. if (!alloc)
  69. alloc = &fz_alloc_default;
  70. if (!locks)
  71. locks = &fz_locks_default;
  72. ctx = new_context_phase1(alloc, locks);
  73. if (!ctx)
  74. return NULL;
  75. /* Now initialise sections that are shared */
  76. fz_try(ctx)
  77. {
  78. fz_new_store_context(ctx, max_store);
  79. fz_new_glyph_cache_context(ctx);
  80. fz_new_font_context(ctx);
  81. }
  82. fz_catch(ctx)
  83. {
  84. fprintf(stderr, "cannot create context (phase 2)\n");
  85. fz_free_context(ctx);
  86. return NULL;
  87. }
  88. return ctx;
  89. }
  90. fz_context *
  91. fz_clone_context(fz_context *ctx)
  92. {
  93. /* We cannot safely clone the context without having locking/
  94. * unlocking functions. */
  95. if (ctx == NULL || ctx->locks == &fz_locks_default)
  96. return NULL;
  97. return fz_clone_context_internal(ctx);
  98. }
  99. fz_context *
  100. fz_clone_context_internal(fz_context *ctx)
  101. {
  102. fz_context *new_ctx;
  103. if (ctx == NULL || ctx->alloc == NULL)
  104. return NULL;
  105. new_ctx = new_context_phase1(ctx->alloc, ctx->locks);
  106. if (!new_ctx)
  107. return NULL;
  108. /* Inherit AA defaults from old context. */
  109. fz_copy_aa_context(new_ctx, ctx);
  110. /* Keep thread lock checking happy by copying pointers first and locking under new context */
  111. new_ctx->store = ctx->store;
  112. new_ctx->store = fz_keep_store_context(new_ctx);
  113. new_ctx->glyph_cache = ctx->glyph_cache;
  114. new_ctx->glyph_cache = fz_keep_glyph_cache(new_ctx);
  115. new_ctx->font = ctx->font;
  116. new_ctx->font = fz_keep_font_context(new_ctx);
  117. return new_ctx;
  118. }