From 41478fd5a1f713f56ec51134d2598700b7f1463c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zdenko=20Podobn=C3=BD?= Date: Fri, 24 Jul 2015 11:51:44 +0200 Subject: [PATCH] implement build without cube (-DNO_CUBE_BUILD) --- Makefile.am | 6 ++++- android/jni/Android.mk | 2 +- api/Makefile.am | 17 ++++++++++----- api/baseapi.cpp | 10 ++++----- api/capi.cpp | 4 ++++ api/capi.h | 6 +++++ api/renderer.h | 2 ++ api/tesseractmain.cpp | 2 ++ ccmain/Makefile.am | 46 ++++++++++++++++++++++----------------- ccmain/control.cpp | 14 ++++++------ ccmain/paramsd.h | 2 +- ccmain/tessedit.cpp | 7 +++++- ccmain/tesseractclass.cpp | 18 +++++++-------- ccmain/tesseractclass.h | 10 ++++----- configure.ac | 13 ++++++++++- cube/cube_utils.cpp | 0 textord/drawedg.h | 2 +- 17 files changed, 103 insertions(+), 58 deletions(-) mode change 100755 => 100644 cube/cube_utils.cpp diff --git a/Makefile.am b/Makefile.am index 7cd8cb89dd..fd7ef30db9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,7 +16,11 @@ endif .PHONY: install-langs ScrollView.jar install-jars $(TRAINING_SUBDIR) -SUBDIRS = ccutil viewer cutil opencl ccstruct dict classify wordrec neural_networks/runtime textord cube ccmain api . tessdata doc +SUBDIRS = ccutil viewer cutil opencl ccstruct dict classify wordrec textord +if !NO_CUBE_BUILD + SUBDIRS += neural_networks/runtime cube +endif +SUBDIRS += ccmain api . tessdata doc EXTRA_DIST = ReleaseNotes \ aclocal.m4 config configure.ac autogen.sh contrib \ diff --git a/android/jni/Android.mk b/android/jni/Android.mk index d8f557e6a1..3b89d6b159 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -47,7 +47,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES:$(LOCAL_PATH)/%=%) $(info local src files = $(LOCAL_SRC_FILES)) LOCAL_LDLIBS := -ldl -llog -ljnigraphics -LOCAL_CFLAGS := -DANDROID_BUILD -DGRAPHICS_DISABLED +LOCAL_CFLAGS := -DNO_CUBE_BUILD -DGRAPHICS_DISABLED include $(BUILD_SHARED_LIBRARY) diff --git a/api/Makefile.am b/api/Makefile.am index 129c31adce..66997c5e91 100644 --- a/api/Makefile.am +++ b/api/Makefile.am @@ -23,8 +23,6 @@ lib_LTLIBRARIES += libtesseract_api.la libtesseract_api_la_LDFLAGS = -version-info $(GENERIC_LIBRARY_VERSION) libtesseract_api_la_LIBADD = \ ../ccmain/libtesseract_main.la \ - ../cube/libtesseract_cube.la \ - ../neural_networks/runtime/libtesseract_neural.la \ ../textord/libtesseract_textord.la \ ../wordrec/libtesseract_wordrec.la \ ../classify/libtesseract_classify.la \ @@ -34,13 +32,17 @@ libtesseract_api_la_LIBADD = \ ../viewer/libtesseract_viewer.la \ ../ccutil/libtesseract_ccutil.la \ ../opencl/libtesseract_opencl.la - + if !NO_CUBE_BUILD + libtesseract_api_la_LIBADD += ../cube/libtesseract_cube.la \ + ../neural_networks/runtime/libtesseract_neural.la \ + endif endif + libtesseract_api_la_CPPFLAGS = $(AM_CPPFLAGS) if VISIBILITY libtesseract_api_la_CPPFLAGS += -DTESS_EXPORTS endif -libtesseract_api_la_SOURCES = baseapi.cpp capi.cpp pdfrenderer.cpp renderer.cpp +libtesseract_api_la_SOURCES = baseapi.cpp capi.cpp renderer.cpp lib_LTLIBRARIES += libtesseract.la libtesseract_la_LDFLAGS = @@ -51,8 +53,6 @@ nodist_EXTRA_libtesseract_la_SOURCES = dummy.cxx libtesseract_la_LIBADD = \ libtesseract_api.la \ ../ccmain/libtesseract_main.la \ - ../cube/libtesseract_cube.la \ - ../neural_networks/runtime/libtesseract_neural.la \ ../textord/libtesseract_textord.la \ ../wordrec/libtesseract_wordrec.la \ ../classify/libtesseract_classify.la \ @@ -62,6 +62,11 @@ libtesseract_la_LIBADD = \ ../viewer/libtesseract_viewer.la \ ../ccutil/libtesseract_ccutil.la \ ../opencl/libtesseract_opencl.la +if !NO_CUBE_BUILD +libtesseract_api_la_SOURCES += pdfrenderer.cpp +libtesseract_la_LIBADD += ../cube/libtesseract_cube.la \ + ../neural_networks/runtime/libtesseract_neural.la +endif libtesseract_la_LDFLAGS += -version-info $(GENERIC_LIBRARY_VERSION) diff --git a/api/baseapi.cpp b/api/baseapi.cpp index 546570909f..3c58f435e0 100644 --- a/api/baseapi.cpp +++ b/api/baseapi.cpp @@ -747,7 +747,7 @@ void TessBaseAPI::DumpPGM(const char* filename) { fclose(fp); } -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD /** * Placeholder for call to Cube and test that the input data is correct. * reskew is the direction of baselines in the skewed image in @@ -1029,7 +1029,7 @@ bool TessBaseAPI::ProcessPagesMultipageTiff(const l_uint8 *data, int timeout_millisec, TessResultRenderer* renderer, int tessedit_page_number) { -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD Pix *pix = NULL; #ifdef USE_OPENCL OpenclDevice od; @@ -1098,7 +1098,7 @@ bool TessBaseAPI::ProcessPagesInternal(const char* filename, const char* retry_config, int timeout_millisec, TessResultRenderer* renderer) { -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD PERF_COUNT_START("ProcessPages") bool stdInput = !strcmp(filename, "stdin") || !strcmp(filename, "-"); if (stdInput) { @@ -1222,7 +1222,7 @@ bool TessBaseAPI::ProcessPage(Pix* pix, int page_index, const char* filename, failed = Recognize(NULL) < 0; } if (tesseract_->tessedit_write_images) { -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD Pix* page_pix = GetThresholdedImage(); pixWrite("tessinput.tif", page_pix, IFF_TIFF_G4); #endif @@ -2633,7 +2633,7 @@ int TessBaseAPI::NumDawgs() const { return tesseract_ == NULL ? 0 : tesseract_->getDict().NumDawgs(); } -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD /** Return a pointer to underlying CubeRecoContext object if present. */ CubeRecoContext *TessBaseAPI::GetCubeRecoContext() const { return (tesseract_ == NULL) ? NULL : tesseract_->GetCubeRecoContext(); diff --git a/api/capi.cpp b/api/capi.cpp index 3710370e90..fc3e9207a8 100644 --- a/api/capi.cpp +++ b/api/capi.cpp @@ -47,10 +47,12 @@ TESS_API TessResultRenderer* TESS_CALL TessHOcrRendererCreate2(const char* outpu return new TessHOcrRenderer(outputbase, font_info); } +#ifndef NO_CUBE_BUILD TESS_API TessResultRenderer* TESS_CALL TessPDFRendererCreate(const char* outputbase, const char* datadir) { return new TessPDFRenderer(outputbase, datadir); } +#endif TESS_API TessResultRenderer* TESS_CALL TessUnlvRendererCreate(const char* outputbase) { @@ -581,10 +583,12 @@ TESS_API void TESS_CALL TessBaseAPIInitTruthCallback(TessBaseAPI* handle, TessTr handle->InitTruthCallback(cb); } +#ifndef NO_CUBE_BUILD TESS_API TessCubeRecoContext* TESS_CALL TessBaseAPIGetCubeRecoContext(const TessBaseAPI* handle) { return handle->GetCubeRecoContext(); } +#endif // NO_CUBE_BUILD TESS_API void TESS_CALL TessBaseAPISetMinOrientationMargin(TessBaseAPI* handle, double margin) { diff --git a/api/capi.h b/api/capi.h index 151cbec588..f0beac3cf8 100644 --- a/api/capi.h +++ b/api/capi.h @@ -33,7 +33,9 @@ extern "C" { typedef tesseract::TessResultRenderer TessResultRenderer; typedef tesseract::TessTextRenderer TessTextRenderer; typedef tesseract::TessHOcrRenderer TessHOcrRenderer; +#ifndef NO_CUBE_BUILD typedef tesseract::TessPDFRenderer TessPDFRenderer; +#endif // NO_CUBE_BUILD typedef tesseract::TessUnlvRenderer TessUnlvRenderer; typedef tesseract::TessBoxTextRenderer TessBoxTextRenderer; typedef tesseract::TessBaseAPI TessBaseAPI; @@ -51,7 +53,9 @@ typedef tesseract::ProbabilityInContextFunc TessProbabilityInContextFunc; typedef tesseract::FillLatticeFunc TessFillLatticeFunc; typedef tesseract::Dawg TessDawg; typedef tesseract::TruthCallback TessTruthCallback; +#ifndef NO_CUBE_BUILD typedef tesseract::CubeRecoContext TessCubeRecoContext; +#endif // NO_CUBE_BUILD typedef tesseract::Orientation TessOrientation; typedef tesseract::ParagraphJustification TessParagraphJustification; typedef tesseract::WritingDirection TessWritingDirection; @@ -295,8 +299,10 @@ TESS_API TessOcrEngineMode TESS_CALL TessBaseAPIOem(const TessBaseAPI* handle); TESS_API void TESS_CALL TessBaseAPIInitTruthCallback(TessBaseAPI* handle, TessTruthCallback* cb); +#ifndef NO_CUBE_BUILD TESS_API TessCubeRecoContext* TESS_CALL TessBaseAPIGetCubeRecoContext(const TessBaseAPI* handle); +#endif // NO_CUBE_BUILD #endif TESS_API void TESS_CALL TessBaseAPISetMinOrientationMargin(TessBaseAPI* handle, double margin); diff --git a/api/renderer.h b/api/renderer.h index 6d189daddf..3a3369b02c 100644 --- a/api/renderer.h +++ b/api/renderer.h @@ -162,6 +162,7 @@ class TESS_API TessHOcrRenderer : public TessResultRenderer { bool font_info_; // whether to print font information }; +#ifndef NO_CUBE_BUILD /** * Renders tesseract output into searchable PDF */ @@ -197,6 +198,7 @@ class TESS_API TessPDFRenderer : public TessResultRenderer { static bool imageToPDFObj(Pix *pix, char *filename, long int objnum, char **pdf_object, long int *pdf_object_size); }; +#endif // NO_CUBE_BUILD /** diff --git a/api/tesseractmain.cpp b/api/tesseractmain.cpp index e7abadf3d0..dcf7ea1f79 100644 --- a/api/tesseractmain.cpp +++ b/api/tesseractmain.cpp @@ -295,11 +295,13 @@ int main(int argc, char **argv) { api.GetBoolVariable("hocr_font_info", &font_info); renderers.push_back(new tesseract::TessHOcrRenderer(outputbase, font_info)); } +#ifndef NO_CUBE_BUILD api.GetBoolVariable("tessedit_create_pdf", &b); if (b) { renderers.push_back(new tesseract::TessPDFRenderer(outputbase, api.GetDatapath())); } +#endif api.GetBoolVariable("tessedit_write_unlv", &b); if (b) renderers.push_back(new tesseract::TessUnlvRenderer(outputbase)); api.GetBoolVariable("tessedit_create_boxfile", &b); diff --git a/ccmain/Makefile.am b/ccmain/Makefile.am index ae6978cbcd..d6c90ac84f 100644 --- a/ccmain/Makefile.am +++ b/ccmain/Makefile.am @@ -4,7 +4,6 @@ AM_CPPFLAGS += \ -I$(top_srcdir)/viewer \ -I$(top_srcdir)/classify -I$(top_srcdir)/dict \ -I$(top_srcdir)/wordrec -I$(top_srcdir)/cutil \ - -I$(top_srcdir)/neural_networks/runtime -I$(top_srcdir)/cube \ -I$(top_srcdir)/textord -I$(top_srcdir)/opencl if USE_OPENCL AM_CPPFLAGS += -I$(OPENCL_HDR_PATH) @@ -15,14 +14,12 @@ AM_CPPFLAGS += -DTESS_EXPORTS \ endif include_HEADERS = \ - thresholder.h ltrresultiterator.h pageiterator.h resultiterator.h \ - osdetect.h + thresholder.h ltrresultiterator.h pageiterator.h resultiterator.h \ + osdetect.h noinst_HEADERS = \ - control.h cube_reco_context.h cubeclassifier.h docqual.h \ - equationdetect.h fixspace.h mutableiterator.h \ + control.h docqual.h equationdetect.h fixspace.h mutableiterator.h \ output.h paragraphs.h paragraphs_internal.h paramsd.h pgedit.h \ - reject.h tessbox.h tessedit.h tesseractclass.h \ - tesseract_cube_combiner.h tessvars.h werdit.h + reject.h tessbox.h tessedit.h tesseractclass.h tessvars.h werdit.h if !USING_MULTIPLELIBS noinst_LTLIBRARIES = libtesseract_main.la @@ -30,28 +27,37 @@ else lib_LTLIBRARIES = libtesseract_main.la libtesseract_main_la_LDFLAGS = -version-info $(GENERIC_LIBRARY_VERSION) libtesseract_main_la_LIBADD = \ - ../wordrec/libtesseract_wordrec.la \ - ../textord/libtesseract_textord.la \ + ../wordrec/libtesseract_wordrec.la \ + ../textord/libtesseract_textord.la \ ../ccutil/libtesseract_ccutil.la \ - ../ccstruct/libtesseract_ccstruct.la \ - ../viewer/libtesseract_viewer.la \ - ../dict/libtesseract_dict.la \ - ../classify/libtesseract_classify.la \ - ../cutil/libtesseract_cutil.la \ - ../cube/libtesseract_cube.la \ - ../opencl/libtesseract_opencl.la - + ../ccstruct/libtesseract_ccstruct.la \ + ../viewer/libtesseract_viewer.la \ + ../dict/libtesseract_dict.la \ + ../classify/libtesseract_classify.la \ + ../cutil/libtesseract_cutil.la \ + ../opencl/libtesseract_opencl.la + if !NO_CUBE_BUILD + libtesseract_main_la_LIBADD += ../cube/libtesseract_cube.la + endif endif libtesseract_main_la_SOURCES = \ - adaptions.cpp applybox.cpp \ - control.cpp cube_control.cpp cube_reco_context.cpp cubeclassifier.cpp \ + adaptions.cpp applybox.cpp control.cpp \ docqual.cpp equationdetect.cpp fixspace.cpp fixxht.cpp \ ltrresultiterator.cpp \ osdetect.cpp output.cpp pageiterator.cpp pagesegmain.cpp \ pagewalk.cpp par_control.cpp paragraphs.cpp paramsd.cpp pgedit.cpp recogtraining.cpp \ reject.cpp resultiterator.cpp superscript.cpp \ - tesseract_cube_combiner.cpp \ tessbox.cpp tessedit.cpp tesseractclass.cpp tessvars.cpp \ tfacepp.cpp thresholder.cpp \ werdit.cpp + +if !NO_CUBE_BUILD +AM_CPPFLAGS += \ + -I$(top_srcdir)/neural_networks/runtime -I$(top_srcdir)/cube +noinst_HEADERS += \ + cube_reco_context.h cubeclassifier.h tesseract_cube_combiner.h +libtesseract_main_la_SOURCES += \ + cube_control.cpp cube_reco_context.cpp cubeclassifier.cpp \ + tesseract_cube_combiner.cpp +endif diff --git a/ccmain/control.cpp b/ccmain/control.cpp index 6113cce0fb..d40c26329b 100644 --- a/ccmain/control.cpp +++ b/ccmain/control.cpp @@ -18,6 +18,11 @@ * **********************************************************************/ +// Include automatically generated configuration file if running autoconf. +#ifdef HAVE_CONFIG_H +#include "config_auto.h" +#endif + #include #include #ifdef __UNIX__ @@ -42,11 +47,6 @@ #include "sorthelper.h" #include "tesseractclass.h" -// Include automatically generated configuration file if running autoconf. -#ifdef HAVE_CONFIG_H -#include "config_auto.h" -#endif - #define MIN_FONT_ROW_COUNT 8 #define MAX_XHEIGHT_DIFF 3 @@ -393,7 +393,7 @@ bool Tesseract::recog_all_words(PAGE_RES* page_res, // ****************** Pass 5,6 ******************* rejection_passes(page_res, monitor, target_word_box, word_config); -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD // ****************** Pass 7 ******************* // Cube combiner. // If cube is loaded and its combiner is present, run it. @@ -1348,7 +1348,7 @@ void Tesseract::classify_word_pass1(const WordData& word_data, BLOCK* block = word_data.block; prev_word_best_choice_ = word_data.prev_word != NULL ? word_data.prev_word->word->best_choice : NULL; -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD // If we only intend to run cube - run it and return. if (tessedit_ocr_engine_mode == OEM_CUBE_ONLY) { cube_word_pass1(block, row, *in_word); diff --git a/ccmain/paramsd.h b/ccmain/paramsd.h index 0214652e5b..c45cebd41c 100644 --- a/ccmain/paramsd.h +++ b/ccmain/paramsd.h @@ -24,7 +24,7 @@ #define VARABLED_H #include "elst.h" -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD #include "scrollview.h" #endif #include "params.h" diff --git a/ccmain/tessedit.cpp b/ccmain/tessedit.cpp index d1fc0d2faf..dd96ba0ebd 100644 --- a/ccmain/tessedit.cpp +++ b/ccmain/tessedit.cpp @@ -19,6 +19,11 @@ * **********************************************************************/ +// Include automatically generated configuration file if running autoconf. +#ifdef HAVE_CONFIG_H +#include "config_auto.h" +#endif + #include "stderr.h" #include "basedir.h" #include "tessvars.h" @@ -200,7 +205,7 @@ bool Tesseract::init_tesseract_lang_data( // engine-specific data files need to be loaded. Currently everything needs // the base tesseract data, which supplies other useful information, but // alternative engines, such as cube and LSTM are optional. -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD if (tessedit_ocr_engine_mode == OEM_CUBE_ONLY) { ASSERT_HOST(init_cube_objects(false, &tessdata_manager)); if (tessdata_manager_debug_level) diff --git a/ccmain/tesseractclass.cpp b/ccmain/tesseractclass.cpp index 25819e8cdd..0c52f0efd9 100644 --- a/ccmain/tesseractclass.cpp +++ b/ccmain/tesseractclass.cpp @@ -34,24 +34,24 @@ // /////////////////////////////////////////////////////////////////////// +// Include automatically generated configuration file if running autoconf. +#ifdef HAVE_CONFIG_H +#include "config_auto.h" +#endif + #include "tesseractclass.h" #include "allheaders.h" -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD #include "cube_reco_context.h" #endif #include "edgblob.h" #include "equationdetect.h" #include "globals.h" -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD #include "tesseract_cube_combiner.h" #endif -// Include automatically generated configuration file if running autoconf. -#ifdef HAVE_CONFIG_H -#include "config_auto.h" -#endif - namespace tesseract { Tesseract::Tesseract() @@ -613,7 +613,7 @@ Tesseract::Tesseract() reskew_(1.0f, 0.0f), most_recently_used_(this), font_table_size_(0), -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD cube_cntxt_(NULL), tess_cube_combiner_(NULL), #endif @@ -624,7 +624,7 @@ Tesseract::~Tesseract() { Clear(); end_tesseract(); sub_langs_.delete_data_pointers(); -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD // Delete cube objects. if (cube_cntxt_ != NULL) { delete cube_cntxt_; diff --git a/ccmain/tesseractclass.h b/ccmain/tesseractclass.h index cd88512043..50141bf942 100644 --- a/ccmain/tesseractclass.h +++ b/ccmain/tesseractclass.h @@ -97,14 +97,14 @@ class WERD_RES; namespace tesseract { class ColumnFinder; -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD class CubeLineObject; class CubeObject; class CubeRecoContext; #endif class EquationDetect; class Tesseract; -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD class TesseractCubeCombiner; #endif @@ -429,7 +429,7 @@ class Tesseract : public Wordrec { int *right_ok) const; //// cube_control.cpp /////////////////////////////////////////////////// -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD bool init_cube_objects(bool load_combiner, TessdataManager *tessdata_manager); // Iterates through tesseract's results and calls cube on each word, @@ -1156,7 +1156,7 @@ class Tesseract : public Wordrec { PAGE_RES_IT* pr_it, FILE *output_file); -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD inline CubeRecoContext *GetCubeRecoContext() { return cube_cntxt_; } #endif @@ -1198,7 +1198,7 @@ class Tesseract : public Wordrec { Tesseract* most_recently_used_; // The size of the font table, ie max possible font id + 1. int font_table_size_; -#ifndef ANDROID_BUILD +#ifndef NO_CUBE_BUILD // Cube objects. CubeRecoContext* cube_cntxt_; TesseractCubeCombiner *tess_cube_combiner_; diff --git a/configure.ac b/configure.ac index 99a57de7df..e7af54472c 100644 --- a/configure.ac +++ b/configure.ac @@ -143,6 +143,17 @@ if test "$enable_graphics" = "no"; then AM_CONDITIONAL(GRAPHICS_DISABLED, true) fi +# Check if cube should be disabled +AC_MSG_CHECKING(whether to disable cube) +AC_ARG_ENABLE([cube], + [AC_HELP_STRING([--disable-cube], [don't build cube support (experimental)])], + [disable_cube="yes"], [disable_cube="no"]) +AC_MSG_RESULT($disable_cube) +AM_CONDITIONAL([NO_CUBE_BUILD], [test "$disable_cube" = "yes"]) +if test "$disable_cube" = "yes"; then + AC_SUBST([AM_CPPFLAGS], [-DNO_CUBE_BUILD]) +fi + # check whether to build embedded version AC_MSG_CHECKING(--enable-embedded argument) AC_ARG_ENABLE([embedded], @@ -211,7 +222,7 @@ AM_CONDITIONAL([USING_MULTIPLELIBS], [test "$enable_mlibs" = "yes"]) AC_MSG_CHECKING(whether to use tessdata-prefix) AC_ARG_ENABLE(tessdata-prefix, [AC_HELP_STRING([--disable-tessdata-prefix], - [dont set TESSDATA-PREFIX during compile])], + [don't set TESSDATA-PREFIX during compile])], [tessdata_prefix="no"], [tessdata_prefix="yes"]) AC_MSG_RESULT($tessdata_prefix) AM_CONDITIONAL([NO_TESSDATA_PREFIX], [test "$tessdata_prefix" = "no"]) diff --git a/cube/cube_utils.cpp b/cube/cube_utils.cpp old mode 100755 new mode 100644 diff --git a/textord/drawedg.h b/textord/drawedg.h index 0d4903ba19..6bf062d4ee 100644 --- a/textord/drawedg.h +++ b/textord/drawedg.h @@ -19,7 +19,7 @@ #ifndef DRAWEDG_H #define DRAWEDG_H -#ifndef ANDROID_BUILD +#ifndef GRAPHICS_DISABLED #include "scrollview.h" #include "crakedge.h"