1 // cfdg.h 2 // this file is part of Context Free 3 // --------------------- 4 // Copyright (C) 2005-2008 Mark Lentczner - markl@glyphic.com 5 // Copyright (C) 2005-2013 John Horigan - john@glyphic.com 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU General Public License 9 // as published by the Free Software Foundation; either version 2 10 // of the License, or (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License 18 // along with this program; if not, write to the Free Software 19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 // 21 // John Horigan can be contacted at john@glyphic.com or at 22 // John Horigan, 1209 Villa St., Mountain View, CA 94041-1123, USA 23 // 24 // Mark Lentczner can be contacted at markl@glyphic.com or at 25 // Mark Lentczner, 1209 Villa St., Mountain View, CA 94041-1123, USA 26 // 27 // 28 29 30 #ifndef INCLUDE_CFDG_H 31 #define INCLUDE_CFDG_H 32 33 #include <iosfwd> 34 #include <string> 35 #include <time.h> 36 #include <vector> 37 #include "agg2/agg_trans_affine.h" 38 #include "agg2/agg_color_rgba.h" 39 #include "agg2/agg_path_storage.h" 40 #include "agg2/agg_pixfmt_rgba.h" 41 #include "location.hh" 42 #include "stacktype.h" 43 #include "Rand64.h" 44 #include "config.h" 45 #include <exception> 46 #include <memory> 47 #include <cstdint> 48 #include <cstddef> 49 50 #define _unused(x) ((void)(x)) 51 52 using RGBA8 = agg::rgba16; 53 54 namespace AST { class ASTcompiledPath; class ASTrule; class ASTparameter; 55 using SymmList = std::vector<agg::trans_affine>; 56 struct CommandInfo; 57 } 58 namespace agg { struct trans_affine_time; } 59 class Shape; 60 class tiledCanvas; 61 class Builder; 62 63 class DeferUntilRuntime : public std::exception { 64 public: 65 virtual const char* what() const noexcept; 66 }; 67 class CfdgError : public std::exception { 68 public: 69 virtual const char* what() const noexcept; 70 CfdgError& operator=(const CfdgError& e) noexcept; 71 yy::location where; 72 static yy::location Default; 73 74 static void Error(const yy::location& errLoc, const char* msg, Builder* b = nullptr); 75 static void Warning(const yy::location& errLoc, const char* msg); 76 77 CfdgError(const yy::location& loc, const char* msg); 78 CfdgError(const char* msg); 79 private: 80 const char* mMsg; 81 }; 82 83 class AbstractSystem { 84 public: 85 enum TempType { ShapeTemp = 0, ExpansionTemp = 1, MergeTemp = 2, MovieTemp = 3, NumberofTempTypes = 4 }; 86 enum SystemSize : std::uint64_t { 87 #if defined(_WIN64) || defined(__x86_64__) 88 MaximumMemory = 17179869184ULL, // 16GB 89 SystemIs64bit = 1 90 #else 91 MaximumMemory = 2147483648ULL, // 2GB 92 SystemIs64bit = 0 93 #endif 94 }; 95 96 #ifdef _WIN32 97 using FileChar = wchar_t; 98 #define FileFormat "%S" 99 #define FileStr(x) L##x 100 #else 101 using FileChar = char; 102 #define FileFormat "%s" 103 #define FileStr(x) x 104 #endif 105 106 using FileString = std::basic_string<FileChar>; 107 using istr_ptr = std::unique_ptr<std::istream>; 108 using ostr_ptr = std::unique_ptr<std::ostream>; 109 110 int cfdgVersion = 2; 111 bool mFirstCfdgRead = true; 112 113 virtual void message(const char* fmt, ...) = 0; 114 virtual void syntaxError(const CfdgError& err) = 0; 115 virtual bool error(bool errorOccurred = true) { return errorOccurred; }; 116 virtual void catastrophicError(const char* what) = 0; isGuiProgram()117 virtual bool isGuiProgram() { return true; } 118 119 virtual istr_ptr openFileForRead(const std::string& path) = 0; 120 virtual istr_ptr tempFileForRead(const FileString& path); 121 virtual ostr_ptr tempFileForWrite(TempType tt, FileString& nameOut) = 0; 122 virtual const FileChar* tempFileDirectory() = 0; 123 // caller must delete returned streams when done 124 virtual std::vector<FileString> findTempFiles() = 0; 125 virtual int deleteTempFile(const FileString& name) = 0; 126 virtual std::size_t getPhysicalMemory() = 0; 127 128 virtual std::string relativeFilePath( 129 const std::string& base, const std::string& rel) = 0; 130 131 virtual std::wstring normalize(const std::string&) = 0; 132 133 struct Stats { 134 int shapeCount; // finished shapes in image 135 int toDoCount; // unfinished shapes still to expand 136 137 bool inOutput; // true if we are in the output loop 138 bool fullOutput; // not an incremental output 139 bool finalOutput; // the last output 140 bool showProgress; 141 int outputCount; // number to be output 142 int outputDone; // number output so far 143 clock_t outputTime; 144 145 bool animating; // inside the animation loop 146 AbstractSystem* mSystem; 147 StatsStats148 Stats() 149 : shapeCount(0), toDoCount(0), inOutput(false), 150 fullOutput(false), finalOutput(false), showProgress(false), 151 outputCount(0), outputDone(0), outputTime(0), animating(false), 152 mSystem(nullptr) {} ~StatsStats153 ~Stats() 154 { 155 // Cancel system progress bar if it is being displayed 156 if (mSystem && (showProgress || inOutput)) { 157 showProgress = inOutput = false; 158 mSystem->stats(*this); 159 } 160 } 161 }; 162 163 virtual void orphan() = 0; 164 165 virtual void stats(const Stats&); 166 167 virtual ~AbstractSystem(); 168 protected: 169 static const FileChar* TempPrefixes[NumberofTempTypes]; 170 static const FileChar* TempSuffixes[NumberofTempTypes]; 171 static const FileChar* TempPrefixAll; clearAndCR()172 virtual void clearAndCR() {}; 173 }; 174 175 class Canvas { 176 public: start(bool,const agg::rgba &,int,int)177 virtual void start(bool , const agg::rgba& , int , int ) 178 { mTime = clock(); } end()179 virtual void end() 180 { mTime = clock() - mTime; } 181 182 virtual void primitive(int, RGBA8 , agg::trans_affine , agg::comp_op_e ) = 0; 183 virtual void path(RGBA8, agg::trans_affine, const AST::CommandInfo& ) = 0; 184 Canvas(int width,int height)185 Canvas(int width, int height) 186 : mWidth(width), mHeight(height), mError(false) {} 187 virtual ~Canvas(); 188 189 int mWidth; 190 int mHeight; 191 clock_t mTime; 192 bool mError; 193 std::string mFileName; 194 }; 195 196 class Renderer; 197 class CFDG; 198 199 using cfdg_ptr = std::shared_ptr<CFDG>; 200 using renderer_ptr = std::unique_ptr<Renderer>; 201 202 class CFDG { 203 public: 204 enum frieze_t { no_frieze = 0, frieze_x, frieze_y }; 205 static cfdg_ptr ParseFile(const char* fname, AbstractSystem*, 206 int variation, std::string defs = ""); 207 virtual ~CFDG(); 208 209 virtual renderer_ptr renderer(const cfdg_ptr& ptr, 210 int width, int height, double minSize, 211 int variation, double border = 2.0 212 ) = 0; 213 // caller must delete returned object 214 215 bool usesColor; 216 bool usesAlpha; 217 bool uses16bitColor; 218 bool usesBlendMode; 219 bool usesTime; 220 bool usesFrameTime; 221 static const CfgArray<std::string> ParamNames; 222 static CFG lookupCfg(const std::string& name); 223 static const std::string& getCfgName(int c); 224 static std::string ShapeToString(int shape); 225 static const AST::ASTparameters* ShapeToParams(int shape); 226 virtual bool isTiled(agg::trans_affine* tr = nullptr, double* x = nullptr, double* y = nullptr) const = 0; 227 virtual frieze_t isFrieze(agg::trans_affine* tr = nullptr, double* x = nullptr, double* y = nullptr) const = 0; 228 virtual bool isSized(double* x = nullptr, double* y = nullptr) const = 0; 229 virtual bool isTimed(agg::trans_affine_time* t = nullptr) const = 0; 230 virtual const agg::rgba& getBackgroundColor() = 0; 231 virtual void serialize(std::ostream&) = 0; 232 233 protected: CFDG()234 CFDG() 235 : usesColor(false), usesAlpha(false), uses16bitColor(false), 236 usesBlendMode(false), usesTime(false), usesFrameTime(false) 237 { } 238 }; 239 240 241 class Renderer { 242 public: 243 // OS interface 244 virtual ~Renderer(); 245 246 virtual void setMaxShapes(int n) = 0; 247 virtual void resetBounds() = 0; 248 virtual void resetSize(int x, int y) = 0; 249 250 virtual double run(Canvas* canvas, bool partialDraw) = 0; 251 virtual void draw(Canvas* canvas) = 0; 252 virtual void animate(Canvas* canvas, int frames, int frame, bool zoom) = 0; 253 254 volatile bool requestStop; // stop ASAP 255 volatile bool requestFinishUp; // stop expanding, and do final output 256 volatile bool requestUpdate; // call stats() soon 257 258 int m_width; 259 int m_height; 260 std::unique_ptr<tiledCanvas> m_tiledCanvas; 261 262 static double Infinity; 263 static bool AbortEverything; 264 static unsigned ParamCount; 265 protected: 266 Renderer(int w, int h); 267 }; 268 269 #endif 270