├── .gitmodules ├── LICENSE ├── README.md ├── scribbleres ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── AppIcon1024x1024.png │ │ ├── AppIcon60x60@2x.png │ │ ├── AppIcon60x60@3x.png │ │ ├── AppIcon76x76@2x.png │ │ ├── AppIcon83.5x83.5@2x.png │ │ └── Contents.json │ ├── Contents.json │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ └── LaunchImage.png ├── GLFW-Makefile.msvc ├── Help.html ├── Intro.svg ├── Makefile ├── SDL-Makefile.ios ├── SDL-Makefile.mac ├── SDL-Makefile.msvc ├── SDL-Makefile.unix ├── SDL209android.patch ├── SDL209win.patch ├── clippings.html ├── embed.py ├── eula.txt ├── fonts │ ├── DroidSansFallback.ttf │ ├── Roboto-Regular.ttf │ ├── SanFranciscoDisplay-Regular.otf │ └── SanFranciscoText-Regular.otf ├── icons │ ├── arrow_down.svg │ ├── arrow_up.svg │ ├── checkbox_check.svg │ ├── checkbox_nocheck.svg │ ├── chevron_down.svg │ ├── chevron_left.svg │ ├── chevron_right.svg │ ├── ic_drive.svg │ ├── ic_file.svg │ ├── ic_folder.svg │ ├── ic_menu_accept.svg │ ├── ic_menu_add_bookmark.svg │ ├── ic_menu_add_doc.svg │ ├── ic_menu_add_folder.svg │ ├── ic_menu_add_people.svg │ ├── ic_menu_add_pic.svg │ ├── ic_menu_append_page.svg │ ├── ic_menu_back.svg │ ├── ic_menu_bookmark.svg │ ├── ic_menu_cancel.svg │ ├── ic_menu_clock.svg │ ├── ic_menu_cloud.svg │ ├── ic_menu_copy.svg │ ├── ic_menu_cut.svg │ ├── ic_menu_discard.svg │ ├── ic_menu_document.svg │ ├── ic_menu_draw.svg │ ├── ic_menu_drawer.svg │ ├── ic_menu_duplicate.svg │ ├── ic_menu_editbox.svg │ ├── ic_menu_ellipsis.svg │ ├── ic_menu_erase.svg │ ├── ic_menu_erase_free.svg │ ├── ic_menu_erase_ruled.svg │ ├── ic_menu_expanddown.svg │ ├── ic_menu_expandright.svg │ ├── ic_menu_folder.svg │ ├── ic_menu_forward.svg │ ├── ic_menu_fullscreen.svg │ ├── ic_menu_help.svg │ ├── ic_menu_insert_space.svg │ ├── ic_menu_insert_space_ruled.svg │ ├── ic_menu_link.svg │ ├── ic_menu_minus.svg │ ├── ic_menu_next.svg │ ├── ic_menu_no_save.svg │ ├── ic_menu_overflow.svg │ ├── ic_menu_pagesel.svg │ ├── ic_menu_pan.svg │ ├── ic_menu_paste.svg │ ├── ic_menu_people.svg │ ├── ic_menu_pin.svg │ ├── ic_menu_plus.svg │ ├── ic_menu_preferences.svg │ ├── ic_menu_prev.svg │ ├── ic_menu_redo.svg │ ├── ic_menu_refresh.svg │ ├── ic_menu_save.svg │ ├── ic_menu_select.svg │ ├── ic_menu_select_lasso.svg │ ├── ic_menu_select_path.svg │ ├── ic_menu_select_ruled.svg │ ├── ic_menu_send.svg │ ├── ic_menu_send_now.svg │ ├── ic_menu_separator.svg │ ├── ic_menu_set_pen.svg │ ├── ic_menu_settings.svg │ ├── ic_menu_share.svg │ ├── ic_menu_split_bt.svg │ ├── ic_menu_split_lr.svg │ ├── ic_menu_split_rl.svg │ ├── ic_menu_split_tb.svg │ ├── ic_menu_stretch.svg │ ├── ic_menu_undo.svg │ ├── ic_menu_zoom.svg │ ├── ic_scroll_handle.svg │ └── write_icon_flat.svg ├── linux │ ├── INSTALL │ ├── Write.desktop │ ├── Write144x144.png │ └── setup.sh ├── macos │ ├── Readme.txt │ └── write.icns ├── pdf2write.sh ├── plotpr.py ├── res_icons.cpp ├── res_strings.cpp ├── strings │ ├── strings-zh-CN.xml │ └── strings.xml └── write_512.png ├── scribbletest ├── scribbletest.cpp ├── scribbletest.h ├── test0_ref.html ├── test10_ref.html ├── test11_ref.html ├── test12_in.html ├── test12_ref.html ├── test13_ref.html ├── test14_ref.html ├── test15_ref.html ├── test16_ref.html ├── test1_in.html ├── test1_ref.html ├── test2_ref.html ├── test3_ref.html ├── test4_ref.html ├── test5_ref.html ├── test6_in.html ├── test6_ref.html ├── test7_ref.html ├── test8_ref.html └── test9_ref.html ├── syncscribble ├── CppProperties.json ├── Makefile ├── Makefile.ios ├── Makefile.mac ├── Makefile.msvc ├── Makefile.unix ├── Makefile.wasm ├── android │ ├── androidhelper.cpp │ ├── androidhelper.h │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets │ │ │ ├── DroidSansFallback.ttf │ │ │ ├── Intro.svg │ │ │ └── Roboto-Regular.ttf │ │ │ ├── java │ │ │ ├── com │ │ │ │ └── styluslabs │ │ │ │ │ └── writeqt │ │ │ │ │ └── MainActivity.java │ │ │ └── org │ │ │ │ └── libsdl │ │ │ │ └── app │ │ │ │ ├── SDL.java │ │ │ │ ├── SDLActivity.java │ │ │ │ └── SDLAudioManager.java │ │ │ ├── jni │ │ │ ├── Android.mk │ │ │ └── Application.mk │ │ │ └── res │ │ │ ├── mipmap-xxhdpi │ │ │ └── icon.png │ │ │ ├── values │ │ │ └── strings.xml │ │ │ └── xml │ │ │ └── filepaths.xml │ ├── build.gradle │ ├── gdb_wrapper │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── gww │ ├── resignapk.sh │ ├── settings.gradle │ └── start_gradle ├── application.cpp ├── application.h ├── basics.cpp ├── basics.h ├── bookmarkview.cpp ├── bookmarkview.h ├── changelog.txt ├── clippingview.cpp ├── clippingview.h ├── configdialog.cpp ├── configdialog.h ├── document.cpp ├── document.h ├── documentlist.cpp ├── documentlist.h ├── element.cpp ├── element.h ├── ios │ ├── AdHoc.app.xcent │ ├── AppStore.app.xcent │ ├── AppStore_Info.plist │ ├── Dev.app.xcent │ ├── IAPDev.app.xcent │ ├── Info.plist │ ├── LaunchView.xib │ ├── Sim.app.xcent │ ├── ioshelper.h │ └── ioshelper.m ├── linkdialog.cpp ├── linkdialog.h ├── linux │ ├── force_glibc.h │ ├── linuxtablet.c │ └── linuxtablet.h ├── macos │ ├── Info.plist │ ├── macoshelper.h │ └── macoshelper.m ├── mainwindow.cpp ├── mainwindow.h ├── page.cpp ├── page.h ├── pentoolbar.cpp ├── pentoolbar.h ├── res_ui.cpp ├── resources.cpp ├── resources.h ├── rulingdialog.cpp ├── rulingdialog.h ├── scribbleapp.cpp ├── scribbleapp.h ├── scribblearea.cpp ├── scribblearea.h ├── scribbleconfig.cpp ├── scribbleconfig.h ├── scribbledoc.cpp ├── scribbledoc.h ├── scribbleinput.cpp ├── scribbleinput.h ├── scribblemode.cpp ├── scribblemode.h ├── scribblepen.h ├── scribblesync.cpp ├── scribblesync.h ├── scribbleview.cpp ├── scribbleview.h ├── scribblewidget.cpp ├── scribblewidget.h ├── selection.cpp ├── selection.h ├── strokebuilder.cpp ├── strokebuilder.h ├── syncdialog.cpp ├── syncdialog.h ├── syncundo.cpp ├── syncundo.h ├── touchwidgets.cpp ├── touchwidgets.h ├── wasm │ ├── wasmhelper.c │ └── wasmhelper.h └── windows │ ├── InstallWrite.wxs │ ├── plain.ico │ ├── resources.rc │ ├── ruled.ico │ ├── winhelper.cpp │ ├── winhelper.h │ ├── wintab │ ├── MSGPACK.H │ ├── PKTDEF.H │ ├── Utils.c │ ├── Utils.h │ ├── WINTAB.H │ └── wmpointer.h │ └── write.ico └── xcode ├── Write ├── Write.xcodeproj │ └── project.pbxproj └── Write │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── AppIcon1024x1024.png │ │ ├── AppIcon60x60@2x.png │ │ ├── AppIcon60x60@3x.png │ │ ├── AppIcon76x76@2x.png │ │ ├── AppIcon83.5x83.5@2x.png │ │ └── Contents.json │ ├── Contents.json │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ └── LaunchImage.png │ ├── Base.lproj │ └── LaunchScreen.storyboard │ ├── Info.plist │ ├── LaunchView.xib │ ├── dummy.cpp │ └── main.m └── WriteIAP ├── Write ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── AppIcon1024x1024.png │ │ ├── AppIcon60x60@2x.png │ │ ├── AppIcon60x60@3x.png │ │ ├── AppIcon76x76@2x.png │ │ ├── AppIcon83.5x83.5@2x.png │ │ └── Contents.json │ ├── Contents.json │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ └── LaunchImage.png ├── Base.lproj │ └── LaunchScreen.storyboard ├── Info.plist ├── LaunchView.xib ├── dummy.cpp └── main.m └── WriteIAP.xcodeproj └── project.pbxproj /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "stb"] 2 | path = stb 3 | url = https://github.com/nothings/stb.git 4 | ignore = untracked 5 | [submodule "pugixml"] 6 | path = pugixml 7 | url = https://github.com/zeux/pugixml.git 8 | ignore = untracked 9 | [submodule "miniz"] 10 | path = miniz 11 | url = https://github.com/richgel999/miniz.git 12 | ignore = untracked 13 | [submodule "SDL"] 14 | path = SDL 15 | url = https://github.com/pbsurf/SDL.git 16 | ignore = untracked 17 | [submodule "nanovgXC"] 18 | path = nanovgXC 19 | url = https://github.com/styluslabs/nanovgXC.git 20 | ignore = untracked 21 | [submodule "ulib"] 22 | path = ulib 23 | url = https://github.com/styluslabs/ulib.git 24 | ignore = untracked 25 | [submodule "usvg"] 26 | path = usvg 27 | url = https://github.com/styluslabs/usvg.git 28 | ignore = untracked 29 | [submodule "ugui"] 30 | path = ugui 31 | url = https://github.com/styluslabs/ugui.git 32 | ignore = untracked 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Write # 2 | 3 | Cross-platform (Windows, Mac, Linux, iOS, Android) application for handwritten notes. 4 | 5 | [styluslabs.com](http://styluslabs.com) | [Help](http://styluslabs.com/write/Help.html) | [FAQ](http://styluslabs.com/faq) 6 | 7 | Screenshot 8 | 9 | 10 | ## Building ## 11 | 12 | Checkout: `git clone --recurse-submodules https://github.com/styluslabs/Write` 13 | 14 | To build executable `syncscribble/Release/Write`: 15 | * Linux: `cd syncscribble && make USE_SYSTEM_SDL=1`; On Debian/Ubuntu, `apt install build-essential libsdl2-dev`. Copy fonts from scribbleres/fonts to syncscribble/Release before running Write. 16 | * Android (on Linux): `cd syncscribble/android && ./gww installRelease`; to install Android SDK and NDK, run `gww --install-sdk` 17 | * iOS: 18 | * build SDL: `cd SDL && git checkout write-mac && make -f ../scribbleres/SDL-Makefile.ios` 19 | * see [nanovgXC readme](https://github.com/styluslabs/nanovgXC?tab=readme-ov-file#example-app) for setup and then run `cd syncscribble && make` or use the [Xcode project](xcode/Write). 20 | * macOS: `cd syncscribble && make MACOS=1` 21 | * Windows: 22 | * install Visual Studio (free Community Edition is fine) and [GNU make for Windows](http://www.equation.com/servlet/equation.cmd?fa=make), ensuring it is available in the path 23 | * in `syncscribble/Makefile`, set `DEPENDBASE` to the parent folder containing all dependencies that `make` should track 24 | * build SDL: `cd SDL && git checkout write-win && make -f ../scribbleres/SDL-Makefile.msvc` 25 | * open a Visual Studio command prompt (from the Start Menu) and run `cd syncscribble && make` 26 | -------------------------------------------------------------------------------- /scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png -------------------------------------------------------------------------------- /scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png -------------------------------------------------------------------------------- /scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png -------------------------------------------------------------------------------- /scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon76x76@2x.png -------------------------------------------------------------------------------- /scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/Assets.xcassets/AppIcon.appiconset/AppIcon83.5x83.5@2x.png -------------------------------------------------------------------------------- /scribbleres/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "AppIcon60x60@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "AppIcon60x60@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "20x20", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "20x20", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "idiom" : "ipad", 57 | "size" : "29x29", 58 | "scale" : "1x" 59 | }, 60 | { 61 | "idiom" : "ipad", 62 | "size" : "29x29", 63 | "scale" : "2x" 64 | }, 65 | { 66 | "idiom" : "ipad", 67 | "size" : "40x40", 68 | "scale" : "1x" 69 | }, 70 | { 71 | "idiom" : "ipad", 72 | "size" : "40x40", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "76x76", 77 | "idiom" : "ipad", 78 | "scale" : "1x" 79 | }, 80 | { 81 | "size" : "76x76", 82 | "idiom" : "ipad", 83 | "filename" : "AppIcon76x76@2x.png", 84 | "scale" : "2x" 85 | }, 86 | { 87 | "size" : "83.5x83.5", 88 | "idiom" : "ipad", 89 | "filename" : "AppIcon83.5x83.5@2x.png", 90 | "scale" : "2x" 91 | }, 92 | { 93 | "size" : "1024x1024", 94 | "idiom" : "ios-marketing", 95 | "filename" : "AppIcon1024x1024.png", 96 | "scale" : "1x" 97 | } 98 | ], 99 | "info" : { 100 | "version" : 1, 101 | "author" : "xcode" 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /scribbleres/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /scribbleres/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /scribbleres/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /scribbleres/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for resources (icons, strings) 2 | # GNU make from v. 3.82 until 4.3 did not return sorted values for wildcard [use $(sort $(wildcard ...))] 3 | 4 | # remove target if building fails 5 | .DELETE_ON_ERROR: 6 | 7 | .PHONY: all clean 8 | 9 | all: res_icons.cpp res_strings.cpp 10 | 11 | res_icons.cpp: icons/*.svg 12 | python3 embed.py $^ > $@ 13 | 14 | res_strings.cpp: strings/*.xml 15 | python3 embed.py --compress $^ > $@ 16 | 17 | clean: 18 | rm res_icons.cpp res_strings.cpp 19 | -------------------------------------------------------------------------------- /scribbleres/SDL-Makefile.mac: -------------------------------------------------------------------------------- 1 | TARGET = libSDL2.a 2 | 3 | SOURCES = \ 4 | src/*.c \ 5 | src/atomic/*.c \ 6 | src/cpuinfo/*.c \ 7 | src/events/*.c \ 8 | src/file/*.c \ 9 | src/file/cocoa/*.m \ 10 | src/filesystem/cocoa/*.m \ 11 | src/loadso/dlopen/*.c \ 12 | src/power/*.c \ 13 | src/render/*.c \ 14 | src/render/metal/*.m \ 15 | src/render/opengles2/*.c \ 16 | src/render/opengl/*.c \ 17 | src/render/software/*.c \ 18 | src/sensor/*.c \ 19 | src/sensor/dummy/*.c \ 20 | src/stdlib/*.c \ 21 | src/thread/*.c \ 22 | src/thread/pthread/*.c \ 23 | src/timer/*.c \ 24 | src/timer/unix/*.c \ 25 | src/video/*.c \ 26 | src/video/dummy/*.c \ 27 | src/video/cocoa/*.m \ 28 | src/video/yuv2rgb/*.c \ 29 | src/main/dummy/SDL_dummy_main.c 30 | 31 | #src/audio/*.c \ 32 | #src/audio/dummy/*.c \ 33 | #src/audio/coreaudio/*.m \ 34 | #src/audio/disk/*.c \ 35 | #src/haptic/*.c \ 36 | #src/haptic/dummy/*.c \ 37 | #src/haptic/darwin/*.c \ 38 | #src/joystick/*.c \ 39 | #src/joystick/darwin/*.c \ 40 | 41 | INC = ./include 42 | INCSYS = ./src/video/khronos 43 | DEFS = SDL_JOYSTICK_DISABLED SDL_AUDIO_DISABLED SDL_HAPTIC_DISABLED 44 | 45 | # common C and C++ flags 46 | CFLAGS = -MMD -Wall -mmacosx-version-min=10.12 47 | # C++ 48 | CXX = g++ 49 | CXXFLAGS = --std=c++14 -fno-rtti -fno-exceptions -Wno-unused-parameter -Wno-unused-function -Wno-unused -Werror=return-type 50 | # C 51 | CC = gcc 52 | CCFLAGS = --std=c99 -Werror=implicit-function-declaration -Werror=int-conversion 53 | # Objective-C 54 | MC = gcc -x objective-c 55 | MFLAGS = 56 | #-fobjc-arc 57 | # ar 58 | AR = libtool -static 59 | ARFLAGS = 60 | 61 | DEBUG ?= 0 62 | ifneq ($(DEBUG), 0) 63 | CFLAGS += -O0 -g 64 | # rdynamic needed to get backtrace symbols from, e.g., catchsegv 65 | LDFLAGS += -rdynamic 66 | BUILDDIR ?= MacDebug 67 | else 68 | CFLAGS += -O2 -DNDEBUG 69 | BUILDDIR ?= MacRelease 70 | endif 71 | 72 | ifneq ($(TOPDIR),) 73 | OBJDIR=$(BUILDDIR)/$(TOPDIR) 74 | else 75 | OBJDIR=$(BUILDDIR) 76 | endif 77 | 78 | # include files 79 | INCFLAGS = $(INC:%=-I%) $(INCSYS:%=-isystem %) $(INCFILES:%=-include %) 80 | 81 | # defines 82 | CFLAGS += $(DEFS:%=-D%) 83 | 84 | ALLSOURCES=$(wildcard $(SOURCES)) 85 | SRCBASE=$(basename $(ALLSOURCES)) 86 | OBJ=$(SRCBASE:%=$(OBJDIR)/%.o) 87 | DEPS=$(SRCBASE:%=$(OBJDIR)/%.d) 88 | TGT=$(BUILDDIR)/$(TARGET) 89 | # gcc will not create directories, so depend on existence of all directories in output folder 90 | # sort removes duplicates (which cause make error) 91 | BUILDDIRS=$(sort $(dir $(OBJ))) 92 | 93 | .PHONY: all clean distclean sourcelist 94 | 95 | all: $(TGT) 96 | 97 | $(OBJDIR)/%.o: %.cpp 98 | $(CXX) -c $(CFLAGS) $(CXXFLAGS) $(INCFLAGS) -o $@ $< 99 | 100 | $(OBJDIR)/%.o: %.c 101 | $(CC) -c $(CFLAGS) $(CCFLAGS) $(INCFLAGS) -o $@ $< 102 | 103 | $(OBJDIR)/%.o: %.m 104 | $(MC) -c $(CFLAGS) $(MFLAGS) $(INCFLAGS) -o $@ $< 105 | 106 | $(TGT): $(OBJ) 107 | $(AR) -o $@ $^ $(ARFLAGS) 108 | 109 | # | (pipe) operator causes make to just check for existence instead of timestamp 110 | $(OBJ): | $(BUILDDIRS) 111 | 112 | $(BUILDDIRS): 113 | mkdir -p $(BUILDDIRS) 114 | 115 | clean: 116 | rm -f $(TGT) $(OBJ) $(DEPS) 117 | 118 | distclean: 119 | rm -rf ./$(BUILDDIR) 120 | 121 | sourcelist: 122 | @printf '%s\n' $(ALLSOURCES) 123 | 124 | # dependency files generated by gcc (-MMD switch) ("-include" ignores file if missing) 125 | -include $(DEPS) 126 | -------------------------------------------------------------------------------- /scribbleres/SDL-Makefile.unix: -------------------------------------------------------------------------------- 1 | TARGET = libSDL2 2 | 3 | # SDL_config_linux.h was taken from cmake build 4 | # To build with cmake: (NOTE we should also disable SSE3, etc.!) 5 | # - in Debug: cmake .. -DSDL_AUDIO=OFF -DSDL_JOYSTICK=OFF -DSDL_HAPTIC=OFF -DSDL_POWER=OFF -DSDL_SENSOR=OFF -DSDL_RENDER=OFF -DSDL_SHARED=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS="-g" 6 | # - in Release: cmake .. -DSDL_AUDIO=OFF -DSDL_JOYSTICK=OFF -DSDL_HAPTIC=OFF -DSDL_POWER=OFF -DSDL_SENSOR=OFF -DSDL_RENDER=OFF -DSDL_SHARED=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Os" 7 | 8 | SOURCES = \ 9 | src/*.c \ 10 | src/atomic/*.c \ 11 | src/core/linux/*.c \ 12 | src/core/unix/*.c \ 13 | src/cpuinfo/*.c \ 14 | src/events/*.c \ 15 | src/file/*.c \ 16 | src/filesystem/unix/*.c \ 17 | src/loadso/dlopen/*.c \ 18 | src/render/*.c \ 19 | src/render/opengles2/*.c \ 20 | src/render/software/*.c \ 21 | src/stdlib/*.c \ 22 | src/thread/*.c \ 23 | src/thread/pthread/*.c \ 24 | src/timer/*.c \ 25 | src/timer/unix/*.c \ 26 | src/video/*.c \ 27 | src/video/dummy/*.c \ 28 | src/video/x11/*.c \ 29 | src/video/yuv2rgb/*.c 30 | 31 | 32 | INC = ./include 33 | INCSYS = /usr/include/dbus-1.0 /usr/lib/x86_64-linux-gnu/dbus-1.0/include /usr/include/ibus-1.0 /usr/include/glib-2.0 /usr/lib/x86_64-linux-gnu/glib-2.0/include 34 | #INCFILES = ../scribbleres/force_link_glibc_2.14.h -- have to build in older chroot environment instead 35 | # SDL_*_DISABLED are defined in SDL_config_linux.h 36 | 37 | ifneq ($(shell git rev-parse --abbrev-ref HEAD),write-linux) 38 | $(error Not on write-linux branch!) 39 | endif 40 | 41 | # common C and C++ flags 42 | CFLAGS = -MMD -Wall -Wshadow -pthread 43 | # C 44 | CC = gcc 45 | CCFLAGS = -Werror=implicit-function-declaration -Werror=int-conversion 46 | # linker 47 | LD = gcc 48 | LDFLAGS = 49 | AR = ar 50 | ARFLAGS = 51 | 52 | DEBUG ?= 0 53 | ifneq ($(DEBUG), 0) 54 | CFLAGS += -O0 -g 55 | # rdynamic needed to get backtrace symbols from, e.g., catchsegv 56 | LDFLAGS += -rdynamic 57 | BUILDDIR ?= Debug 58 | TARGET := $(TARGET)d 59 | else 60 | CFLAGS += -Os -DNDEBUG 61 | BUILDDIR ?= Release 62 | endif 63 | 64 | ifneq ($(TOPDIR),) 65 | OBJDIR=$(BUILDDIR)/$(TOPDIR) 66 | else 67 | OBJDIR=$(BUILDDIR) 68 | endif 69 | 70 | # include files 71 | INCFLAGS = $(INC:%=-I%) $(INCSYS:%=-isystem %) $(INCFILES:%=-include %) 72 | 73 | # defines 74 | CFLAGS += $(DEFS:%=-D%) 75 | 76 | ALLSOURCES=$(wildcard $(SOURCES)) 77 | SRCBASE=$(basename $(ALLSOURCES)) 78 | OBJ=$(SRCBASE:%=$(OBJDIR)/%.o) 79 | DEPS=$(SRCBASE:%=$(OBJDIR)/%.d) 80 | TGT=$(BUILDDIR)/$(TARGET).a 81 | # gcc will not create directories, so depend on existence of all directories in output folder 82 | # sort removes duplicates (which cause make error) 83 | BUILDDIRS=$(sort $(dir $(OBJ))) 84 | 85 | .PHONY: all clean distclean sourcelist 86 | 87 | all: $(TGT) 88 | 89 | $(OBJDIR)/%.o: %.c 90 | $(CC) -c $(CFLAGS) $(CCFLAGS) $(INCFLAGS) -o $@ $< 91 | 92 | $(TGT): $(OBJ) 93 | $(AR) cr$(ARFLAGS) $@ $^ 94 | 95 | # | (pipe) operator causes make to just check for existence instead of timestamp 96 | $(OBJ): | $(BUILDDIRS) 97 | 98 | $(BUILDDIRS): 99 | mkdir -p $(BUILDDIRS) 100 | 101 | clean: 102 | rm -f $(TGT) $(OBJ) $(DEPS) 103 | 104 | distclean: 105 | rm -rf ./Debug ./Release 106 | 107 | sourcelist: 108 | @printf '%s\n' $(SOURCES) 109 | 110 | # dependency files generated by gcc (-MMD switch) ("-include" ignores file if missing) 111 | -include $(DEPS) 112 | -------------------------------------------------------------------------------- /scribbleres/SDL209android.patch: -------------------------------------------------------------------------------- 1 | diff -r 8feb5da6f2fb src/dynapi/SDL_dynapi.h 2 | --- a/src/dynapi/SDL_dynapi.h Tue Oct 30 20:11:02 2018 +0300 3 | +++ b/src/dynapi/SDL_dynapi.h Sat Jun 13 21:12:43 2020 -0700 4 | @@ -59,7 +59,7 @@ 5 | 6 | /* everyone else. This is where we turn on the API if nothing forced it off. */ 7 | #ifndef SDL_DYNAMIC_API 8 | -#define SDL_DYNAMIC_API 1 9 | +#define SDL_DYNAMIC_API 0 10 | #endif 11 | 12 | #endif 13 | diff -r 8feb5da6f2fb src/video/SDL_video.c 14 | --- a/src/video/SDL_video.c Tue Oct 30 20:11:02 2018 +0300 15 | +++ b/src/video/SDL_video.c Sat Jun 13 21:12:43 2020 -0700 16 | @@ -1436,7 +1436,7 @@ 17 | } 18 | 19 | /* Some platforms have OpenGL enabled by default */ 20 | -#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__ 21 | +#if 0 /*(SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__*/ 22 | if (!_this->is_dummy && !(flags & SDL_WINDOW_VULKAN)) { 23 | flags |= SDL_WINDOW_OPENGL; 24 | } 25 | diff -r 8feb5da6f2fb src/video/android/SDL_androidwindow.c 26 | --- a/src/video/android/SDL_androidwindow.c Tue Oct 30 20:11:02 2018 +0300 27 | +++ b/src/video/android/SDL_androidwindow.c Sat Jun 13 21:12:43 2020 -0700 28 | @@ -77,7 +77,7 @@ 29 | 30 | /* Do not create EGLSurface for Vulkan window since it will then make the window 31 | incompatible with vkCreateAndroidSurfaceKHR */ 32 | - if ((window->flags & SDL_WINDOW_VULKAN) == 0) { 33 | + if ((window->flags & SDL_WINDOW_OPENGL)) { /*VULKAN) == 0) {*/ 34 | data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window); 35 | 36 | if (data->egl_surface == EGL_NO_SURFACE) { 37 | -------------------------------------------------------------------------------- /scribbleres/embed.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # generate C++ source file from list of text files 3 | 4 | # usage: python embed.py icons/*.svg > res_icons.cpp 5 | # `chmod 555 res_icons.cpp` might be a good idea 6 | 7 | # Alternative approaches: 8 | # - https://stackoverflow.com/questions/4158900/embedding-resources-in-executable-using-gcc 9 | # - https://stackoverflow.com/questions/4864866/c-c-with-gcc-statically-add-resource-files-to-executable-library 10 | # - https://github.com/graphitemaster/incbin (Macro for using .incbin) 11 | # inline assembly with .incbin would be my preferred approach, except that it doesn't work with MSVC 12 | 13 | import sys 14 | import subprocess 15 | 16 | sys.argv.pop(0) 17 | compress = False 18 | if sys.argv[0] == "--compress": 19 | compress = True 20 | sys.argv.pop(0) 21 | 22 | c_out = ['// Generated by embed.py\n\n'] 23 | h_out = [] #['#pragma once\n\n'] 24 | for filename in sys.argv: 25 | varname = filename.replace('.', '_').replace('/', '__').replace('\\', '__').replace('-', '_') 26 | if compress: 27 | h_out.append('{"%s", {%s, sizeof(%s)}}' % (filename, varname, varname)) 28 | c_out.append('static const unsigned char ' + varname + '[] = {\n') 29 | # replacements are to try to avoid whitespace changes if file is opened and saved in an editor 30 | c_out.append(subprocess.check_output("gzip -c %s | xxd -i" % filename, shell=True, encoding='UTF-8')) 31 | c_out.append('};\n\n') 32 | else: 33 | h_out.append('{"' + filename + '", ' + varname + '}') 34 | with open(filename, 'r') as f: 35 | c_out.append('static const char* ' + varname + ' = R"~~~~(') 36 | # replacements are to try to avoid whitespace changes if file is opened and saved in an editor 37 | c_out.append(f.read().replace("\t", " ").replace("\r\n", "\n")) 38 | c_out.append(')~~~~";\n\n') 39 | 40 | c_out.append('static void LOAD_RES_FN() { addStringResources({\n %s\n}); }\n' % ',\n '.join(h_out)) 41 | c_out.append('#undef LOAD_RES_FN\n') 42 | 43 | print(''.join(c_out)) 44 | -------------------------------------------------------------------------------- /scribbleres/eula.txt: -------------------------------------------------------------------------------- 1 | End-User License Agreement for Stylus Labs Write 2 | 3 | This End-User License Agreement ("EULA") is a legal agreement between you, either an individual or a single entity, ("LICENSEE") and Stylus Labs ("LICENSOR") for the software product identified above, which includes computer software and may include associated media and "online" or electronic documentation ("SOFTWARE PRODUCT"). 4 | 5 | By installing, copying, or otherwise using the SOFTWARE PRODUCT, the LICENSEE agrees to be bound by the terms of this EULA. 6 | 7 | SOFTWARE PRODUCT LICENSE 8 | 9 | 1. GRANT OF LICENSE. This EULA grants the LICENSEE the following rights: Installation and Use. LICENSEE may install and use an unlimited number of copies of the SOFTWARE PRODUCT. The LICENSOR reserves all rights in the SOFTWARE PRODUCT not expressly granted to LICENSEE herein. 10 | 11 | a) Reproduction and Distribution. 12 | The LICENSEE may not reproduce or distribute the SOFTWARE PRODUCT. 13 | 14 | b) Termination. 15 | Without prejudice to any other rights, the LICENSOR may terminate this EULA if the LICENSEE fails to comply with the terms and conditions of this EULA. In such event, the LICENSEE must destroy all copies of the SOFTWARE PRODUCT and all of its component parts. 16 | 17 | 2. LIMITATION ON REVERSE ENGINEERING. 18 | The LICENSEE may not reverse engineer, decompile, or disassemble the SOFTWARE PRODUCT, except and only to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation. 19 | 20 | 3. COPYRIGHT. 21 | All title and copyrights in and to the SOFTWARE PRODUCT, the accompanying documentation, and any copies of the SOFTWARE PRODUCT are owned by the LICENSOR. The SOFTWARE PRODUCT is protected by copyright laws and international treaty provisions. 22 | 23 | 4. NO WARRANTIES. 24 | The LICENSOR expressly disclaims any warranty for the SOFTWARE PRODUCT. The SOFTWARE PRODUCT and any related documentation is provided "as is" without warranty of any kind, either express or implied, including, without limitation, the implied warranties or merchantability, fitness for a particular purpose, or noninfringement. The entire risk arising out of use or performance of the SOFTWARE PRODUCT remains with the LICENSEE. 25 | 26 | 5. NO LIABILITY FOR DAMAGES. 27 | In no event shall the LICENSOR be liable for any special, consequential, incidental or indirect damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or any other pecuniary loss) arising out of the use of or inability to use this product, even if the LICENSOR is aware of the possibility of such damages and known defects. 28 | -------------------------------------------------------------------------------- /scribbleres/fonts/DroidSansFallback.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/fonts/DroidSansFallback.ttf -------------------------------------------------------------------------------- /scribbleres/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /scribbleres/fonts/SanFranciscoDisplay-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/fonts/SanFranciscoDisplay-Regular.otf -------------------------------------------------------------------------------- /scribbleres/fonts/SanFranciscoText-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/fonts/SanFranciscoText-Regular.otf -------------------------------------------------------------------------------- /scribbleres/icons/arrow_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/arrow_up.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/checkbox_check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /scribbleres/icons/checkbox_nocheck.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /scribbleres/icons/chevron_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /scribbleres/icons/chevron_left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /scribbleres/icons/chevron_right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_drive.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_file.svg: -------------------------------------------------------------------------------- 1 | 2 | 11 | 14 | 21 | 25 | 29 | 30 | 33 | 40 | 44 | 48 | 49 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 10 | 14 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_accept.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_add_bookmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_add_doc.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_add_folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_add_people.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_add_pic.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_append_page.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_back.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_bookmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_cancel.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_clock.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_cloud.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_cut.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 22 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_discard.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_document.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_draw.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_drawer.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_duplicate.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_editbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_ellipsis.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_erase.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_erase_free.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_erase_ruled.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_expanddown.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_expandright.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_forward.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_help.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 21 | 22 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_insert_space.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_insert_space_ruled.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_link.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_minus.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_next.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_no_save.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_overflow.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_pagesel.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_pan.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_paste.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_people.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_preferences.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_prev.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_redo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_refresh.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_save.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_select.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_select_lasso.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_select_path.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_select_ruled.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_send.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_send_now.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_separator.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_set_pen.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_settings.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_share.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_split_bt.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_split_lr.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_split_rl.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_split_tb.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_stretch.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_undo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_menu_zoom.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scribbleres/icons/ic_scroll_handle.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scribbleres/icons/write_icon_flat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /scribbleres/linux/INSTALL: -------------------------------------------------------------------------------- 1 | Make sure your graphics driver is up-to-date, then run ./setup.sh 2 | This script will install the SDL2 library required by Write and 3 | create a desktop entry. 4 | 5 | If Write's interface appears too small (or too large), enable 6 | advanced preferences and enter the actual DPI (= horizontal 7 | pixels/horizontal size in inches) for "Screen DPI" in the 8 | Advanced section, then restart Write. You may also wish to 9 | adjust the default page size in Page Setup. 10 | 11 | To remove the desktop entry created by Write, run: 12 | rm ~/.local/share/applications/Write.desktop 13 | -------------------------------------------------------------------------------- /scribbleres/linux/Write.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | # desktop entry spec version 4 | Version=1.0 5 | Name=Write 6 | Comment=A word processor for handwriting 7 | Exec=/opt/Write/Write 8 | Icon=Write144x144 9 | MimeType=image/svg+xml; 10 | Terminal=false 11 | Categories=Education 12 | -------------------------------------------------------------------------------- /scribbleres/linux/Write144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/linux/Write144x144.png -------------------------------------------------------------------------------- /scribbleres/linux/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" 4 | 5 | if ! $SCRIPTPATH/Write --exit >/dev/null 2>&1 ; then 6 | echo "Installing SDL2 library - this may prompt for password to install package" 7 | command -v yum >/dev/null 2>&1 && sudo yum install SDL2 8 | command -v pacman >/dev/null 2>&1 && sudo pacman -S sdl2 9 | command -v apt-get >/dev/null 2>&1 && (dpkg -s libsdl2-2.0-0 >/dev/null 2>&1 || sudo apt-get install libsdl2-2.0-0) 10 | 11 | if ! $SCRIPTPATH/Write --exit; then 12 | echo "\nERROR: Unable to setup Write - please make sure SDL2 (libsdl2) is installed and that your graphics driver supports OpenGL 3.3 or later" 13 | exit 1 14 | fi 15 | fi 16 | 17 | if ! command -v desktop-file-edit >/dev/null 2>&1 ; then 18 | echo "\nIf you would like to create a desktop entry for Write, please install the desktop-file-utils package and run this script again" 19 | else 20 | DESKTOPFILE=$SCRIPTPATH/Write.desktop 21 | desktop-file-edit --set-key=Exec --set-value=$SCRIPTPATH/Write $DESKTOPFILE 22 | desktop-file-edit --set-key=Icon --set-value=$SCRIPTPATH/Write144x144.png $DESKTOPFILE 23 | #sudo desktop-file-install $DESKTOPFILE # to install for all users 24 | desktop-file-install --dir=$HOME/.local/share/applications $DESKTOPFILE 25 | echo "\nCreated desktop entry for Write" 26 | fi 27 | 28 | echo "*** Setup succeeded ***" 29 | -------------------------------------------------------------------------------- /scribbleres/macos/Readme.txt: -------------------------------------------------------------------------------- 1 | How to install: 2 | 1. drag Write to the Applications link 3 | 2. open the Applications link, right click on Write, choose Open, and click Open in the dialog 4 | -------------------------------------------------------------------------------- /scribbleres/macos/write.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/macos/write.icns -------------------------------------------------------------------------------- /scribbleres/pdf2write.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Create a Write document from a PDF by generating page images 3 | 4 | echo "Converting PDF to images..." 5 | (command -v pdftoppm >/dev/null 2>&1 && pdftoppm -png -r 300 $1 out) || convert -density 300 -scene 1 $1 out-%03d.png 6 | if [ ! -f "out-1.png" ] && [ ! -f "out-01.png" ] && [ ! -f "out-001.png" ]; then 7 | echo "No page images found: make sure pdftoppm (from poppler-utils) or imagemagick and ghostscript are installed" 8 | exit 1 9 | fi 10 | SVGOUT=$(basename $1 pdf)svg 11 | echo "Generating Write document..." 12 | 13 | printf '\n' > $SVGOUT 14 | printf '\n' >> $SVGOUT 15 | 16 | for PNGPAGE in out-*.png 17 | do 18 | read WIDTH2 HEIGHT2 < <(identify -format "%w %h" $PNGPAGE) 19 | # page images generated at 300 DPI but Write uses 150 DPI as reference 20 | WIDTH=$((WIDTH2/2)) 21 | HEIGHT=$((HEIGHT2/2)) 22 | 23 | printf '\n' $WIDTH $HEIGHT >> $SVGOUT 24 | printf ' \n' >> $SVGOUT 25 | printf ' \n' >> $SVGOUT 26 | printf ' \n' $WIDTH $HEIGHT >> $SVGOUT 27 | 28 | printf ' \n \n \n' >> $SVGOUT 32 | done 33 | 34 | printf "\n" >> $SVGOUT 35 | 36 | gzip -S z $SVGOUT 37 | rm out-*.png 38 | echo "Finished creating $SVGOUT"z 39 | -------------------------------------------------------------------------------- /scribbleres/plotpr.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | from matplotlib.collections import LineCollection 4 | 5 | def plotpr(str): 6 | #v = [[(ii, float(x)) for ii, x in enumerate(line.strip().split())] for line in str if line.strip() and not line.startswith('#')] 7 | 8 | v = [[float(x) for x in line.strip().split()] for line in str if line.strip() and not line.startswith('#')] 9 | ml = np.mean([len(x) for x in v]) 10 | 11 | avgd = {} 12 | for s in v: 13 | if(len(s) <= 2*ml): 14 | avgd.setdefault(len(s), []).append(s) 15 | z = [np.transpose([np.arange(len(a[0])), np.mean(a, axis=0)]) for a in avgd.values()] 16 | 17 | c = LineCollection(z, linewidths=0.25) 18 | 19 | fig, ax = plt.subplots() 20 | ax.add_collection(c) 21 | #ax.autoscale() 22 | plt.axis([0, 2*ml, 0, 1.1]) 23 | plt.ion() 24 | plt.show() 25 | 26 | 27 | def plotfile(filename): 28 | with open(filename) as f: 29 | plotpr(f) 30 | plt.title(filename) 31 | 32 | 33 | def plot(*args, **kwargs): 34 | #import matplotlib.pyplot as plt 35 | plt.ion() # interactive mode - make plot window non-blocking 36 | plt.figure() 37 | plt.plot(*args) 38 | if 'xlabel' in kwargs: plt.xlabel(kwargs['xlabel']) 39 | if 'ylabel' in kwargs: plt.ylabel(kwargs['ylabel']) 40 | if 'title' in kwargs: plt.title(kwargs['title']) 41 | plt.show() 42 | 43 | 44 | #plotpr(str.splitlines()) #sys.stdin) 45 | 46 | # plotfile('x61.pr') 47 | # plotfile('yoga1.pr') 48 | # plotfile('ipad2.pr') 49 | # plotfile('tpt.pr') 50 | # plotfile('spen.pr') 51 | 52 | cpp_code = """ 53 | //createAction("actionDumpPressures", "Dump Pressures", "", "Ctrl+`", [this](){ 54 | // fprintf(stderr, "# Dumping selected strokes\n\n"); 55 | // if(!app->activeArea()->currSelection) return; 56 | // for(Element* s : app->activeArea()->currSelection->strokes) { 57 | // s->dumpPressures(); 58 | // } 59 | // printf("\n"); 60 | //}); 61 | 62 | //void Element::dumpPressures() 63 | //{ 64 | // if(penPoints.empty()) 65 | // penPoints = toPenPoints(); 66 | // Dim sw = node->getFloatAttr("stroke-width", 1); 67 | // for(PenPoint& p : penPoints) { 68 | // Dim pr = 1 - pow(std::max(0.0, 1 - p.dr.dist()/sw), 0.5); 69 | // printf("%.3f ", pr); 70 | // } 71 | // printf("\n"); 72 | //} 73 | """ 74 | -------------------------------------------------------------------------------- /scribbleres/write_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/scribbleres/write_512.png -------------------------------------------------------------------------------- /scribbletest/scribbletest.h: -------------------------------------------------------------------------------- 1 | #ifndef SCRIBBLETEST_H 2 | #define SCRIBBLETEST_H 3 | 4 | #include "scribbledoc.h" 5 | #include "bookmarkview.h" 6 | 7 | class ScribbleTest 8 | { 9 | friend class ScribbleApp; 10 | public: 11 | ScribbleTest(const std::string &path); 12 | ScribbleTest(ScribbleDoc* sd, BookmarkView* bv, ScribbleMode* sm); 13 | ~ScribbleTest(); 14 | 15 | void runAll(bool runsynctest = false); 16 | void performanceTest(); 17 | void inputTest(); 18 | void syncSlaveMsg(std::string msg, int level); 19 | 20 | // result string to be read by caller 21 | std::string resultStr; 22 | 23 | private: 24 | ScribbleConfig* scribbleConfig; 25 | ScribbleDoc* scribbleDoc; 26 | ScribbleArea* scribbleArea; 27 | ScribbleMode* scribbleMode; 28 | BookmarkView* bookmarkArea; 29 | Image* screenImg; 30 | Painter* screenPaint; 31 | Rect screenRect; 32 | std::string outPath; 33 | int nFailed; 34 | 35 | // shared whiteboard testing 36 | pugi::xml_document swbXML; 37 | ScribbleTest* syncSlave; 38 | int syncTestNum; 39 | bool waitForSyncDone; 40 | void startSyncTest(int testnum); 41 | void waitForSync(); 42 | void checkStrokeMap(ScribbleDoc* doc, const char* msg); 43 | 44 | static const int pen = INPUTSOURCE_PEN; 45 | static const int press = INPUTEVENT_PRESS; 46 | static const int release = INPUTEVENT_RELEASE; 47 | void undo() { scribbleDoc->doCommand(ID_UNDO); } 48 | void redo() { scribbleDoc->doCommand(ID_REDO); } 49 | void doCommand(int cmd) { scribbleDoc->doCommand(cmd); } 50 | bool testCompareFiles(const char* f1, const char* f2, bool svgonly = false); 51 | void ie(Dim x, Dim y, Dim p, int src, int ev = 0, int mm = 0); 52 | void mtinput(inputevent_t ev1, Dim x1, Dim y1, inputevent_t ev2, Dim x2, Dim y2); 53 | void ss(Dim offset); 54 | void s1(Dim xoffset, Dim yoffset); 55 | void s2(Dim xoffset, Dim yoffset); 56 | void s3(Dim xoffset, Dim yoffset); 57 | void f2(Dim xoffset, Dim yoffset); 58 | void hr(Dim xoffset, Dim yoffset); 59 | void s3(); 60 | void s4(); 61 | 62 | void test0(); 63 | void test1(); 64 | void test2(); 65 | void test3(); 66 | void test4(); 67 | void test5(); 68 | void test6(); 69 | void test7(); 70 | void test8(); 71 | void test9(); 72 | void test10(); 73 | void test11(); 74 | void test12(); 75 | void test13(); 76 | void test14(); 77 | void test15(); 78 | void synctest01(); 79 | void synctest01slave1(); 80 | void synctest01slave2(); 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /scribbletest/test12_in.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Handwritten Document 6 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /scribbletest/test1_in.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Handwritten Document 6 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 36 | 37 | 38 | 43 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /syncscribble/android/app/src/main/assets/DroidSansFallback.ttf: -------------------------------------------------------------------------------- 1 | ../../../../../../scribbleres/fonts/DroidSansFallback.ttf -------------------------------------------------------------------------------- /syncscribble/android/app/src/main/assets/Intro.svg: -------------------------------------------------------------------------------- 1 | ../../../../../../scribbleres/Intro.svg -------------------------------------------------------------------------------- /syncscribble/android/app/src/main/assets/Roboto-Regular.ttf: -------------------------------------------------------------------------------- 1 | ../../../../../../scribbleres/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /syncscribble/android/app/src/main/java/org/libsdl/app/SDL.java: -------------------------------------------------------------------------------- 1 | package org.libsdl.app; 2 | 3 | import android.content.Context; 4 | 5 | import java.lang.reflect.*; 6 | 7 | /** 8 | SDL library initialization 9 | */ 10 | public class SDL { 11 | 12 | // This function should be called first and sets up the native code 13 | // so it can call into the Java classes 14 | public static void setupJNI() { 15 | SDLActivity.nativeSetupJNI(); 16 | SDLAudioManager.nativeSetupJNI(); 17 | //SDLControllerManager.nativeSetupJNI(); 18 | } 19 | 20 | // This function should be called each time the activity is started 21 | public static void initialize() { 22 | setContext(null); 23 | 24 | SDLActivity.initialize(); 25 | SDLAudioManager.initialize(); 26 | //SDLControllerManager.initialize(); 27 | } 28 | 29 | // This function stores the current activity (SDL or not) 30 | public static void setContext(Context context) { 31 | mContext = context; 32 | } 33 | 34 | public static Context getContext() { 35 | return mContext; 36 | } 37 | 38 | public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException { 39 | 40 | if (libraryName == null) { 41 | throw new NullPointerException("No library name provided."); 42 | } 43 | 44 | try { 45 | // Let's see if we have ReLinker available in the project. This is necessary for 46 | // some projects that have huge numbers of local libraries bundled, and thus may 47 | // trip a bug in Android's native library loader which ReLinker works around. (If 48 | // loadLibrary works properly, ReLinker will simply use the normal Android method 49 | // internally.) 50 | // 51 | // To use ReLinker, just add it as a dependency. For more information, see 52 | // https://github.com/KeepSafe/ReLinker for ReLinker's repository. 53 | // 54 | Class relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker"); 55 | Class relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener"); 56 | Class contextClass = mContext.getClassLoader().loadClass("android.content.Context"); 57 | Class stringClass = mContext.getClassLoader().loadClass("java.lang.String"); 58 | 59 | // Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if 60 | // they've changed during updates. 61 | Method forceMethod = relinkClass.getDeclaredMethod("force"); 62 | Object relinkInstance = forceMethod.invoke(null); 63 | Class relinkInstanceClass = relinkInstance.getClass(); 64 | 65 | // Actually load the library! 66 | Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass); 67 | loadMethod.invoke(relinkInstance, mContext, libraryName, null, null); 68 | } 69 | catch (final Throwable e) { 70 | // Fall back 71 | try { 72 | System.loadLibrary(libraryName); 73 | } 74 | catch (final UnsatisfiedLinkError ule) { 75 | throw ule; 76 | } 77 | catch (final SecurityException se) { 78 | throw se; 79 | } 80 | } 81 | } 82 | 83 | protected static Context mContext; 84 | } 85 | -------------------------------------------------------------------------------- /syncscribble/android/app/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | #include $(call all-subdir-makefiles) 2 | 3 | # Note that symlinking source dirs is a terrible idea which can create a huge mess when trying to open files, 4 | # esp. when debugging 5 | include /home/mwhite/styluslabs/SDL/Android.mk 6 | include /home/mwhite/styluslabs/syncscribble/Makefile 7 | -------------------------------------------------------------------------------- /syncscribble/android/app/src/main/jni/Application.mk: -------------------------------------------------------------------------------- 1 | # See https://developer.android.com/ndk/guides/cpp-support 2 | APP_STL := c++_shared 3 | 4 | # these are set in build.gradle now 5 | #APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 6 | #APP_PLATFORM=android-18 7 | 8 | #APP_CPPFLAGS := -fno-exceptions -fno-rtti -Wno-narrowing 9 | -------------------------------------------------------------------------------- /syncscribble/android/app/src/main/res/mipmap-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/syncscribble/android/app/src/main/res/mipmap-xxhdpi/icon.png -------------------------------------------------------------------------------- /syncscribble/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Write 3 | 4 | -------------------------------------------------------------------------------- /syncscribble/android/app/src/main/res/xml/filepaths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /syncscribble/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:8.4.0' 10 | 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | google() 19 | mavenCentral() 20 | } 21 | } 22 | 23 | task clean(type: Delete) { 24 | delete rootProject.buildDir 25 | } 26 | -------------------------------------------------------------------------------- /syncscribble/android/gdb_wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$1" = "-version" ]; then 4 | exec /home/mwhite/android-ndk-r18b/prebuilt/linux-x86_64/bin/gdb -version 5 | else 6 | # Qt Creator sends SIGINT to debugger process by PID in order to pause inferior (necessary, e.g., for 7 | # setting breakpoints) ... but SIGINT does not get propagated to children, so we have to `exec` gdb so 8 | # that this PID is gdb itself. 9 | # NOTE: we also edited NDK's `gdb`, a bash script itself, to use `exec`. 10 | # Possible alternative would be python script to run gdb and catch SIGINT to forward to gdb 11 | exec /home/mwhite/android-ndk-r18b/prebuilt/linux-x86_64/bin/gdb -x /home/mwhite/graphics/syncscribble/android/debug_start.gdb "$@" 12 | 13 | # now done at beginning of debug_start.sh 14 | #/home/mwhite/android-sdk/platform-tools/adb forward --remove tcp:5039 15 | fi 16 | -------------------------------------------------------------------------------- /syncscribble/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Nov 11 18:20:34 PST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /syncscribble/android/gww: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Notes: 3 | # - arguments: "assembleRelease" to build APK, "installRelease" to build APK and install on connected device 4 | # - to view log messages from just Maps: 5 | # /home/mwhite/android-sdk/platform-tools/adb logcat | grep -e Tangram -e StylusLabs 6 | 7 | set -e 8 | 9 | if [ "$1" = "--install-sdk" ]; then 10 | java --version || sudo apt install openjdk-17-jdk 11 | mkdir $HOME/android-sdk && pushd $HOME/android-sdk 12 | curl https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip --output cmdline-tools.zip 13 | unzip cmdline-tools.zip 14 | cmdline-tools/bin/sdkmanager --sdk_root=. --install 'build-tools;34.0.0' 'platforms;android-34' 'platform-tools' 'ndk;26.3.11579264' 'cmake;3.18.1' 15 | #cmdline-tools/bin/sdkmanager --sdk_root=. --install 'build-tools;30.0.3' 'platforms;android-30' 'platform-tools' 'ndk;23.1.7779620' 'cmake;3.18.1' 16 | popd 17 | exit 0 18 | fi 19 | 20 | # gradle expects people to add their binary file to git! And doesn't provide a way to just download gradle wrapper! 21 | # ... other gradle wrapper wrappers do crazy things like download the entire gradle dist (>100MB) to install the wrapper, 22 | # which will in turn download gradle again! And why is gradle-wrapper.jar 60KB when it just downloads and runs another 23 | # program, which this script accomplishes in a few lines? 24 | if [ ! -f ./gradlew ]; then 25 | mkdir -p ./gradle/wrapper 26 | # we need to specify gradle version in gradle-wrapper.properties 27 | #curl 'https://raw.githubusercontent.com/libsdl-org/SDL/main/android-project/gradle/wrapper/gradle-wrapper.properties' --output ./gradle/wrapper/gradle-wrapper.properties 28 | curl 'https://raw.githubusercontent.com/libsdl-org/SDL/main/android-project/gradle/wrapper/gradle-wrapper.jar' --output ./gradle/wrapper/gradle-wrapper.jar 29 | curl 'https://raw.githubusercontent.com/libsdl-org/SDL/main/android-project/gradlew' --output gradlew 30 | chmod 755 gradlew 31 | fi 32 | 33 | [ -z "$ANDROID_HOME" ] && export ANDROID_HOME="$HOME/android-sdk" 34 | ./gradlew "$@" 35 | -------------------------------------------------------------------------------- /syncscribble/android/resignapk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Sample usage is as follows; 3 | # ./signapk myapp.apk styluslabs.keystore styluslabs 4 | # 5 | # param1, APK file: Calculator_debug.apk 6 | # param2, keystore location: ~/.android/debug.keystore 7 | set -x 8 | 9 | BUILD_TOOLS="$HOME/android-sdk/build-tools/34.0.0" 10 | 11 | # use my debug key default 12 | APK=$1 13 | KEYSTORE=$2 14 | 15 | # get the filename 16 | APK_BASENAME=$(basename $APK) 17 | SIGNED_APK="signed_"$APK_BASENAME 18 | 19 | # delete META-INF folder 20 | zip -d $APK META-INF/\* 21 | 22 | $BUILD_TOOLS/zipalign -v -p 4 $APK $SIGNED_APK 23 | 24 | $BUILD_TOOLS/apksigner sign --ks $KEYSTORE $SIGNED_APK 25 | 26 | $BUILD_TOOLS/apksigner verify $SIGNED_APK 27 | -------------------------------------------------------------------------------- /syncscribble/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /syncscribble/android/start_gradle: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PATH="/home/mwhite/android-sdk/platform-tools:$PATH" 3 | export ANDROID_HOME="/home/mwhite/android-sdk" 4 | 5 | ./gradlew $@ 6 | -------------------------------------------------------------------------------- /syncscribble/application.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "resources.h" 6 | 7 | class Painter; 8 | class SvgGui; 9 | class Window; 10 | class Dialog; 11 | struct SDL_Window; 12 | 13 | class Application 14 | { 15 | public: 16 | static SvgGui* gui; 17 | 18 | static void setupUIScale(float horzdpi = 0); 19 | static bool processEvents(); 20 | static void layoutAndDrawSW(); 21 | static void layoutAndDrawGL(); 22 | static void layoutAndDraw(); 23 | static void execWindow(Window* w); 24 | static int execDialog(Dialog* dialog); 25 | static void asyncDialog(Dialog* dialog, const std::function& callback = NULL); 26 | static void finish() { runApplication = false; } 27 | 28 | //private: 29 | static bool runApplication; 30 | static bool glRender; 31 | static bool isSuspended; 32 | static SDL_Window* sdlWindow; 33 | static Painter* painter; 34 | static std::string appDir; 35 | }; 36 | -------------------------------------------------------------------------------- /syncscribble/basics.cpp: -------------------------------------------------------------------------------- 1 | #include "basics.h" 2 | 3 | #ifdef NDEBUG 4 | bool SCRIBBLE_DEBUG = false; 5 | #else 6 | bool SCRIBBLE_DEBUG = true; 7 | #endif 8 | -------------------------------------------------------------------------------- /syncscribble/basics.h: -------------------------------------------------------------------------------- 1 | #ifndef BASICS_H 2 | #define BASICS_H 3 | 4 | #include "ulib/platformutil.h" 5 | #include "ulib/stringutil.h" 6 | #include "ulib/fileutil.h" 7 | 8 | 9 | #define SCRIBBLE_LOG PLATFORM_LOG 10 | 11 | typedef double Dim; 12 | typedef int64_t Timestamp; 13 | 14 | #define MIN std::min 15 | #define MAX std::max 16 | #define ABS std::abs 17 | #define SGN(x) ((x) >= 0 ? 1 : -1) 18 | //#define CLAMP(x, min, max) std::min(MAX(x, min), max) 19 | // number of elements in an array 20 | #define NELEM(a) (sizeof(a)/sizeof(a[0])) 21 | #define NELEMI(a) ((int)(sizeof(a)/sizeof(a[0]))) 22 | 23 | #define MAX_DIM REAL_MAX 24 | #define MIN_DIM REAL_MIN 25 | // previously, we had MIN/MAX_X/Y_DIM to provide better annotation, but they weren't used consistently 26 | 27 | #ifndef NDEBUG 28 | #define SCRIBBLE_TEST 1 29 | #endif 30 | 31 | extern bool SCRIBBLE_DEBUG; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /syncscribble/bookmarkview.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOKMARKVIEW_H 2 | #define BOOKMARKVIEW_H 3 | 4 | #include "scribbleview.h" 5 | 6 | class ScribbleDoc; 7 | //class Element; 8 | #include "page.h" 9 | 10 | class BookmarkView : public ScribbleView 11 | { 12 | friend class ScribbleTest; 13 | public: 14 | enum Mode {BOOKMARKS=0, MARGIN_CONTENT=1}; 15 | 16 | BookmarkView(ScribbleConfig* _cfg, ScribbleDoc* doc); 17 | void setScribbleDoc(ScribbleDoc* doc); 18 | void repaintBookmarks(); 19 | Element* bookmarkHit = NULL; 20 | 21 | void loadConfig(ScribbleConfig* _cfg) override; 22 | void unHighlightHit(); 23 | 24 | protected: 25 | void doPressEvent(const InputEvent& event) override; 26 | void doMoveEvent(const InputEvent& event) override; 27 | void doReleaseEvent(const InputEvent& event) override; 28 | bool doClickAction(Point pos) override; 29 | void doCancelAction(bool refresh = true) override; 30 | void doMotionEvent(const InputEvent& event, inputevent_t eventtype) override; 31 | void doRefresh() override; 32 | 33 | void pageSizeChanged() override; 34 | void drawImage(Painter* imgpaint, const Rect& dirty) override; 35 | void getContentDim(Dim viewwidth, Dim viewheight); 36 | 37 | void highlightHit(Point pos); 38 | void drawBookmarks(Painter* painter, Document* doc, const Rect& dirty); 39 | void drawPageBookmarks(Painter* painter, Page* page, Dim ypos, Dim xmin, int nbkmks); 40 | Element* findBookmark(Document* doc, Dim bookmarky, int* pagenumout = NULL); 41 | 42 | ScribbleDoc* scribbleDoc = NULL; 43 | Rect hitDirtyRect; 44 | Dim bookmarksHeight = 0; 45 | }; 46 | 47 | #endif // BOOKMARKVIEW_H 48 | -------------------------------------------------------------------------------- /syncscribble/clippingview.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "scribblearea.h" 4 | 5 | class Widget; 6 | 7 | class ClippingView : public ScribbleArea 8 | { 9 | public: 10 | void loadConfig(ScribbleConfig* _cfg) override; 11 | bool selectionDropped(Selection* selection, Point pos, Point offset, bool replaceids = false) override; 12 | void deleteClipping(); 13 | 14 | Widget* delTarget; 15 | 16 | protected: 17 | void doPressEvent(const InputEvent& event) override; 18 | void doMoveEvent(const InputEvent& event) override; 19 | void doReleaseEvent(const InputEvent& event) override; 20 | bool doClickAction(Point pos) override; 21 | void doCancelAction(bool refresh = true) override; 22 | void pageSizeChanged() override; 23 | 24 | int clipNum; 25 | Point globalPos; 26 | Point selOffset; 27 | }; 28 | -------------------------------------------------------------------------------- /syncscribble/configdialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "scribbleconfig.h" 4 | #include "ugui/widgets.h" 5 | 6 | class ConfigDialog : public Dialog 7 | { 8 | public: 9 | ConfigDialog(ScribbleConfig* _cfg); 10 | void accept(); 11 | void resetPrefs(); 12 | void toggleAdvPrefs(bool show); 13 | 14 | private: 15 | void init(); 16 | 17 | ScribbleConfig* cfg = NULL; 18 | Widget* toolStack; 19 | std::vector allprops; 20 | typedef std::map PropGroups_t; 21 | PropGroups_t propGroups; 22 | }; 23 | -------------------------------------------------------------------------------- /syncscribble/document.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ulib/fileutil.h" 4 | #include "ulib/miniz_gzip.h" 5 | #include "page.h" 6 | #include "syncundo.h" 7 | #include "pugixml.hpp" 8 | 9 | struct DocPosition { 10 | int pagenum; 11 | Point pos; 12 | 13 | DocPosition(int _pagenum = -1, Dim x = 0, Dim y = 0) : pagenum(_pagenum), pos(x, y) {} 14 | DocPosition(int _pagenum, Point _pos) : pagenum(_pagenum), pos(_pos) {} 15 | }; 16 | 17 | struct DocViewBox { 18 | int pagenum; 19 | Rect box; 20 | Dim zoom; 21 | 22 | DocViewBox(int pp = -1, const Rect& r = Rect(), Dim z = 1) : pagenum(pp), box(r), zoom(z) {} 23 | bool operator==(const DocViewBox& b) { return pagenum == b.pagenum && box == b.box; } 24 | bool operator!=(const DocViewBox& b) { return !operator==(b); } 25 | bool isValid() { return pagenum >= 0 && box.isValid(); } 26 | }; 27 | 28 | class Document { 29 | public: 30 | std::vector pages; 31 | UndoHistory* history; 32 | int dirtyCount = 0; // managed just as Page.dirtyCount 33 | int autoSaveSerialNum = 0; 34 | bool bookmarksDirty = false; 35 | pugi::xml_document xmldoc; 36 | 37 | std::unique_ptr blockStream; 38 | std::vector blockInfo; 39 | 40 | enum loadresult_t {LOAD_OK=0, LOAD_FATAL=-1, LOAD_NONFATAL=-2, LOAD_EMPTYDOC=-3, LOAD_NEWERVERSION=-4, LOAD_NONWRITE=-5}; 41 | // document format version 42 | static const int docFormatVersion = 2; 43 | // save flags 44 | typedef unsigned int saveflags_t; 45 | static constexpr saveflags_t SAVE_NORMAL = 0x0, SAVE_FORCE = 0x1, SAVE_MULTIFILE = 0x2, SAVE_COPY = 0x4, 46 | /*SAVE_AUTO_BACKUP = 0x8,*/ SAVE_BGZ_PARTIAL = 0x10; 47 | static size_t memoryLimit; 48 | 49 | Document(); 50 | ~Document(); 51 | int insertPage(Page* p, int where = -1); 52 | Page* deletePage(int where); // , bool delstrokes = false); 53 | bool ensurePagesLoaded(); 54 | bool checkAndClearErrors(); 55 | pugi::xml_node resetConfigNode(pugi::xml_node newcfg = pugi::xml_node()); 56 | pugi::xml_node getConfigNode(); 57 | 58 | SvgNode* findNamedNode(const char* idstr, int* pagenumout = NULL) const; 59 | Page* pageForElement(const Element* s) const; 60 | int pageNumForElement(const Element* s) const; 61 | 62 | bool save(IOStream* outstrm, const char* thumb, saveflags_t flags = SAVE_NORMAL); 63 | loadresult_t load(IOStream* instrm, bool delayload = false); 64 | loadresult_t load(const pugi::xml_document& doc, const char* path= "", bool delayload = false, bool ok = true); 65 | bool deleteFiles(); 66 | bool isModified() const; 67 | bool isEmptyFile() const; 68 | int numPages() const { return int(pages.size()); } 69 | 70 | bool saveBgz(IOStream* outstrm, const char* thumb, saveflags_t flags); 71 | bool loadBgzPage(Page* page); 72 | Document::loadresult_t loadBgzDoc(IOStream* instrm); 73 | const char* fileName() const { return blockStream ? blockStream->name() : ""; } 74 | void checkMemoryUsage(int currpage); 75 | }; 76 | -------------------------------------------------------------------------------- /syncscribble/documentlist.h: -------------------------------------------------------------------------------- 1 | #ifndef DOCUMENTLIST_H 2 | #define DOCUMENTLIST_H 3 | 4 | #include "ugui/widgets.h" 5 | #include "ugui/textedit.h" 6 | #include "basics.h" 7 | 8 | class ScribbleApp; 9 | 10 | class NewDocDialog : public Dialog 11 | { 12 | public: 13 | NewDocDialog(const char* title, const FSPath& fsinfo, bool newdoc = false); 14 | 15 | std::string getName() const { return StringRef(nameEdit->text()).trimmed().toString(); } 16 | TextEdit* nameEdit = NULL; 17 | ComboBox* comboRuling = NULL; 18 | Toolbar* msgBar = NULL; 19 | }; 20 | 21 | class DocumentList : public Window 22 | { 23 | public: 24 | DocumentList(const char* root, const char* temp); 25 | //~DocumentList() { MainWindow::removeDir(trashPath, true); } 26 | 27 | std::string selectedFile; // filename out 28 | std::string selectedSrcFile; // source file when opening copy of file 29 | enum Result_t {REJECTED = 0, NEW_DOC, EXISTING_DOC, OPEN_COPY, OPEN_WHITEBOARD, OPEN_HELP} result; // out 30 | int selectedRuling; 31 | 32 | enum Mode_t {OPEN_DOC, CHOOSE_DOC, CHOOSE_IMAGE, SAVE_DOC, SAVE_PDF}; 33 | bool isMultiFileDoc(const FSPath& fileinfo) const; 34 | void setup(Window* parent, Mode_t mode = OPEN_DOC, const char* exts = NULL, bool cancelable = true); 35 | void finish(Result_t result); 36 | 37 | static bool copyDocument(const FSPath& src, const FSPath& dest, bool move); 38 | 39 | std::function onFinished; 40 | 41 | protected: 42 | void cutItem(); 43 | void copyItem(); 44 | void openCopyItem(); 45 | void renameItem(); 46 | void deleteItem(); 47 | void pasteItem(); 48 | void newDoc(); 49 | void newFolder(); 50 | void openWhiteboard(); 51 | void clearClipboard(); 52 | void undoDelete(); 53 | void hideUndo(); 54 | void refresh(); 55 | 56 | private: 57 | //SvgGui* svgGui; 58 | std::string docFileExt; 59 | std::string fileExts; 60 | Button* newFolderBtn; 61 | Button* newDocBtn; 62 | Button* pasteButton; 63 | Button* undoButton; 64 | Button* helpBtn; 65 | Button* whiteboardBtn; 66 | Button* contextMenuCopy; 67 | Button* contextMenuOpenCopy; 68 | Button* saveHereBtn; 69 | Button* cancelChoose; 70 | Button* zoomIn; 71 | Button* zoomOut; 72 | Toolbar* pasteBar; 73 | Toolbar* undoBar; 74 | Toolbar* msgBar; 75 | Widget* listView; 76 | Menu* contextMenu; 77 | ScrollWidget* scrollWidget; 78 | //Widget* mainWindow; 79 | std::unique_ptr listItemProto; 80 | std::unique_ptr gridItemProto; 81 | std::vector breadCrumbs; 82 | Button* drivesBtn; 83 | #if PLATFORM_ANDROID 84 | Button* privateDirBtn; 85 | Button* sharedDirBtn; 86 | #endif 87 | 88 | std::unique_ptr fileUseNode; 89 | std::unique_ptr folderUseNode; 90 | int iconWidth; 91 | 92 | FSPath docRoot; 93 | bool docListSiloed = false; 94 | FSPath undoDeleteDir; 95 | FSPath trashPath; 96 | 97 | FSPath currDir; 98 | FSPath contextMenuItem; 99 | FSPath clipboard; 100 | bool cutClipboard; 101 | Mode_t currMode = OPEN_DOC; //chooseOnly; 102 | 103 | void setCurrDir(const char* path); 104 | void createUI(); 105 | bool convertDocuments(FSPath src); 106 | void zoomListView(int step); 107 | }; 108 | 109 | #endif // DOCUMENTLIST_H 110 | -------------------------------------------------------------------------------- /syncscribble/ios/AdHoc.app.xcent: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | application-identifier 6 | 8U8646Y4MM.com.styluslabs.write3 7 | com.apple.developer.team-identifier 8 | 8U8646Y4MM 9 | get-task-allow 10 | 11 | keychain-access-groups 12 | 13 | 8U8646Y4MM.com.styluslabs.write3 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /syncscribble/ios/AppStore.app.xcent: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | application-identifier 6 | 8U8646Y4MM.com.styluslabs.write3 7 | com.apple.developer.team-identifier 8 | 8U8646Y4MM 9 | get-task-allow 10 | 11 | beta-reports-active 12 | 13 | keychain-access-groups 14 | 15 | 8U8646Y4MM.com.styluslabs.write3 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /syncscribble/ios/AppStore_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Write 9 | CFBundleDocumentTypes 10 | 11 | 12 | CFBundleTypeName 13 | public.svg-image 14 | CFBundleTypeRole 15 | Editor 16 | LSHandlerRank 17 | Default 18 | LSItemContentTypes 19 | 20 | public.svg-image 21 | 22 | 23 | 24 | CFBundleExecutable 25 | Write 26 | CFBundleIcons 27 | 28 | CFBundlePrimaryIcon 29 | 30 | CFBundleIconFiles 31 | 32 | AppIcon60x60 33 | 34 | CFBundleIconName 35 | AppIcon 36 | 37 | 38 | CFBundleIcons~ipad 39 | 40 | CFBundlePrimaryIcon 41 | 42 | CFBundleIconFiles 43 | 44 | AppIcon60x60 45 | AppIcon76x76 46 | 47 | CFBundleIconName 48 | AppIcon 49 | 50 | 51 | CFBundleIdentifier 52 | com.styluslabs.write3 53 | CFBundleInfoDictionaryVersion 54 | 6.0 55 | CFBundleName 56 | Write 57 | CFBundlePackageType 58 | APPL 59 | CFBundleShortVersionString 60 | $(MARKETING_VERSION) 61 | CFBundleSupportedPlatforms 62 | 63 | iPhoneOS 64 | 65 | CFBundleVersion 66 | $(CURRENT_PROJECT_VERSION) 67 | ITSAppUsesNonExemptEncryption 68 | 69 | LSRequiresIPhoneOS 70 | 71 | LSSupportsOpeningDocumentsInPlace 72 | 73 | NSPhotoLibraryAddUsageDescription 74 | Write can save an image of the document to your photo library for easy sharing. 75 | UIFileSharingEnabled 76 | 77 | UILaunchStoryboardName 78 | LaunchView 79 | UIRequiredDeviceCapabilities 80 | 81 | arm64 82 | metal 83 | opengles-3 84 | 85 | UISupportedInterfaceOrientations 86 | 87 | UIInterfaceOrientationPortrait 88 | UIInterfaceOrientationPortraitUpsideDown 89 | UIInterfaceOrientationLandscapeLeft 90 | UIInterfaceOrientationLandscapeRight 91 | 92 | UISupportsDocumentBrowser 93 | 94 | UIViewControllerBasedStatusBarAppearance 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /syncscribble/ios/Dev.app.xcent: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | application-identifier 6 | 8U8646Y4MM.com.styluslabs.write3 7 | com.apple.developer.team-identifier 8 | 8U8646Y4MM 9 | get-task-allow 10 | 11 | keychain-access-groups 12 | 13 | 8U8646Y4MM.com.styluslabs.write3 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /syncscribble/ios/IAPDev.app.xcent: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | application-identifier 6 | 8U8646Y4MM.com.styluslabs.write3a 7 | com.apple.developer.team-identifier 8 | 8U8646Y4MM 9 | get-task-allow 10 | 11 | keychain-access-groups 12 | 13 | 8U8646Y4MM.com.styluslabs.write3a 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /syncscribble/ios/LaunchView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /syncscribble/ios/Sim.app.xcent: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.get-task-allow 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /syncscribble/ios/ioshelper.h: -------------------------------------------------------------------------------- 1 | #ifndef IOSHELPER_H 2 | #define IOSHELPER_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | extern void iosPumpEventsBlocking(void); 8 | extern void iosWakeEventLoop(void); 9 | extern void showImagePicker(void); 10 | extern void iosOpenUrl(const char* url); 11 | extern void iosRequestReview(void); 12 | extern const char* iosGetLocale(void); 13 | extern void iosSendFile(const char* filename); 14 | extern int iosClipboardChangeCount(void); 15 | extern int iosGetClipboardImage(void); 16 | extern int iosSafeAreaInsets(float* top, float* bottom); 17 | 18 | //extern void freeSecuredURL(void* data); 19 | extern void initDocumentBrowser(const char* bkmkBase64); 20 | extern void showDocumentBrowser(void); 21 | extern void iosCloseDocument(void* _doc); 22 | extern void iosSaveDocument(void* _doc, void* data, int len); 23 | extern char* iosGetSecuredBookmark(void* _doc); 24 | extern void iosSetDocThumbnail(void* _doc, void* data, int width, int height); 25 | extern void iosSaveAs(long mode); 26 | extern void iosPickDocument(long mode); 27 | 28 | enum PickerMode_t { iosOpenDocMode = 0, iosUpdateDocMode, iosChooseDocMode, iosInsertDocMode, 29 | iosSaveAsMode, iosExportPdfMode, iosConflictSaveMode }; 30 | 31 | // functions expected to be available in Write 32 | extern void imagePicked(const void* data, int len, int fromclip); 33 | extern void pencilBarrelTap(void); 34 | extern void* loadDocumentContents(void* data, size_t len, size_t reserve, const char* url, void* uidoc); 35 | extern const char* getCfgString(const char* name, const char* dflt); 36 | extern const char* _(const char*); // translations 37 | 38 | #ifdef SCRIBBLE_IAP 39 | extern int iosIsPaid(void); 40 | extern void iosRequestIAP(void); 41 | extern void iapCompleted(void); // expected in Write 42 | #endif 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /syncscribble/linkdialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ugui/widgets.h" 4 | #include "bookmarkview.h" 5 | #include "touchwidgets.h" 6 | 7 | class ScribbleDoc; 8 | class BookmarkSelect; 9 | class TextEdit; 10 | 11 | class LinkDialog : public Dialog 12 | { 13 | public: 14 | LinkDialog(ScribbleDoc* sd); 15 | void bookmarkSelected(Element* b); 16 | void accept(); 17 | 18 | private: 19 | ColorEditBox* penColorPicker; 20 | ScribbleDoc* scribbleDoc; 21 | TextEdit* hrefEdit; 22 | std::unique_ptr bookmarkSelect; 23 | }; 24 | 25 | class BookmarkSelect : public BookmarkView 26 | { 27 | public: 28 | BookmarkSelect(LinkDialog* parent, ScribbleConfig* _cfg, ScribbleDoc* target); 29 | ~BookmarkSelect(); 30 | 31 | protected: 32 | bool doClickAction(Point pos) override; 33 | void doDblClickAction(Point pos) override; 34 | 35 | LinkDialog* linkDialog; 36 | }; 37 | -------------------------------------------------------------------------------- /syncscribble/linux/force_glibc.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is taken from force_link_glibc_2.19.h (Ubuntu 14.04 era) from https://github.com/wheybags/glibc_version_header - technically libstdc++ must be recomplied with this header too, but it seems that for Write, only pow() and exp() use a recent glibc version, so it should be safe. To be extra safe, we will only override pow() and exp(). But we have to take care if we update libstdc++ (currently using g++ 8.2)! 3 | 4 | Use `strings | grep "GLIBC_"` to see what symbol versions are being requested. 5 | 6 | The correct way to build a portable application for Linux is to just build on the oldest version of Linux you want to support. In theory, cross-compiling with, e.g., github.com/theopolis/build-anywhere is possible, but requires all dependencies be rebuilt (including, e.g, X11) ... so unless a recent compiler is essential, it's easier to just build 7 | on an old version of Linux. 8 | 9 | Update Oct 2022: glibc 2.34 introduces __libc_start_main@GLIBC_2.34 which cannot be prevented with symver, at least not without 10 | something like -nostdlib -nostartfiles, or editing the ELF ( https://www.lightofdawn.org/wiki/wiki.cgi/NewAppsOnOldGlibc ), or 11 | perhaps -Wl,--wrap ... In any case, some libstdc++ (GLIBCXX) fn versions have also been updated, so we have to give up on the 12 | symver hack and just build with an older toolchain. Fortunately, debootstrap makes it easy to setup an older version of Debian 13 | in a chroot. 14 | */ 15 | 16 | #if !defined(SET_GLIBC_LINK_VERSIONS_HEADER) && !defined(__ASSEMBLER__) 17 | #define SET_GLIBC_LINK_VERSIONS_HEADER 18 | __asm__(".symver exp,exp@GLIBC_2.2.5"); 19 | __asm__(".symver pow,pow@GLIBC_2.2.5"); 20 | __asm__(".symver log,log@GLIBC_2.2.5"); 21 | __asm__(".symver expf,expf@GLIBC_2.2.5"); 22 | __asm__(".symver powf,powf@GLIBC_2.2.5"); 23 | __asm__(".symver logf,logf@GLIBC_2.2.5"); 24 | #endif 25 | -------------------------------------------------------------------------------- /syncscribble/linux/linuxtablet.h: -------------------------------------------------------------------------------- 1 | #ifndef LINUXTABLET_H 2 | #define LINUXTABLET_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | struct SDL_Window; 8 | union SDL_Event; 9 | int linuxInitTablet(SDL_Window* sdlwin); 10 | //void linuxPollTablet(void); 11 | void linuxProcessXEvent(SDL_Event* event); 12 | //void linuxCloseTablet(void); 13 | int requestClipboard(SDL_Window* sdlwin); 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /syncscribble/macos/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrincipalClass 6 | NSApplication 7 | NSHighResolutionCapable 8 | 9 | CFBundleIconFile 10 | write.icns 11 | CFBundlePackageType 12 | APPL 13 | CFBundleGetInfoString 14 | Created by Stylus Labs 15 | CFBundleSignature 16 | ???? 17 | CFBundleExecutable 18 | Write 19 | CFBundleIdentifier 20 | com.styluslabs.write3mac 21 | 22 | 23 | -------------------------------------------------------------------------------- /syncscribble/macos/macoshelper.h: -------------------------------------------------------------------------------- 1 | #ifndef MACOSHELPER_H 2 | #define MACOSHELPER_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | extern void macosWaitEvent(void); 8 | //extern void macosPumpEvents(void); 9 | extern void macosWakeEventLoop(void); 10 | extern void macosDisableMouseCoalescing(void); 11 | extern int macosOpenUrl(const char* url); 12 | extern int macosClipboardChangeCount(void); 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /syncscribble/pentoolbar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ugui/widgets.h" 4 | #include "basics.h" 5 | #include "scribbleconfig.h" 6 | 7 | 8 | class ScribbleApp; 9 | class ColorEditBox; 10 | class PenPreview; 11 | 12 | // idea here is to abstract a container for a group of widgets that handles overflow, currently w/ an overflow 13 | // menu, but scrolling could be another option 14 | class PaletteWidget : public Widget 15 | { 16 | public: 17 | //PaletteWidget(SvgNode* n, Widget* main, Widget* overflow, Widget* btn); 18 | PaletteWidget(SvgNode* n) : Widget(n) {} 19 | // we could add insert and delete methods in the future if needed 20 | void addButton(Button* w); 21 | void setNumVisible(int n); 22 | void clear(); 23 | 24 | std::vector items; 25 | Widget* mainGroup = NULL; 26 | Widget* overflowGroup = NULL; 27 | Widget* overflowBtn = NULL; 28 | int numMainGroup; 29 | }; 30 | 31 | class PenToolbar : public Toolbar 32 | { 33 | public: 34 | PenToolbar(); 35 | 36 | ScribblePen pen; 37 | enum Mode { PEN_MODE, BOOKMARK_MODE, SELECTION_MODE } mode = PEN_MODE; 38 | 39 | void saveConfig(ScribbleConfig* cfg) const; 40 | void updateColor(); 41 | void updateWidth(); 42 | void updatePen(); 43 | void setPen(const ScribblePen& newpen, Mode m); 44 | //void dragWidth(int delta); 45 | 46 | enum ChangedFlag { COLOR_CHANGED=1, WIDTH_CHANGED=2, PEN_CHANGED=4, YIELD_FOCUS=8, 47 | UNDO_PREV=0x10000, SAVE_PEN=0x20000 }; 48 | std::function onChanged; 49 | 50 | // access needded for auto adjust 51 | PaletteWidget* colorPalette; 52 | PaletteWidget* widthPalette; 53 | Widget* stretch; 54 | Button* closeBtn; 55 | 56 | const Dim penWidthPreviewMax = 22; // was 30 for circle instead of line; static constexpr only works for int 57 | 58 | private: 59 | void rebuildGrids(); 60 | void updateWidthPicker(bool varw, bool chisel); 61 | 62 | Button* cbHighlight; 63 | Button* cbSnaptoGrid; 64 | Button* cbLineDrawing; 65 | Button* cbEphemeral; 66 | //Button* comboPressure; 67 | Button* comboSavePen; 68 | ColorEditBox* colorPicker; 69 | SpinBox* spinWidth; 70 | Button* widthPreview; 71 | Widget* colorGroup; 72 | Widget* widthGroup; 73 | 74 | // advanced pen options 75 | PenPreview* penPreview; 76 | ComboBox* comboPenTip; 77 | SpinBox* spinRatio; 78 | SpinBox* spinPrPrm; 79 | SpinBox* spinMaxSp; 80 | SpinBox* spinAngle; 81 | SpinBox* spinDash; 82 | SpinBox* spinGap; 83 | CheckBox* cbRatio; 84 | CheckBox* cbPrPrm; 85 | CheckBox* cbMaxSp; 86 | CheckBox* cbAngle; 87 | Widget* rowRatio; 88 | Widget* rowPrPrm; 89 | Widget* rowMaxSp; 90 | Widget* rowAngle; 91 | Widget* rowDash; 92 | Widget* rowGap; 93 | 94 | Button* overflowBtn; 95 | Button* selOverflowBtn; 96 | Menu* colorCtxMenu; 97 | Menu* widthCtxMenu; 98 | Button* colorMenuDelete; 99 | Button* widthMenuDelete; 100 | Dim preScale; 101 | 102 | int changesSinceFocused = -1; 103 | int contextMenuIdx; 104 | std::vector savedColors; 105 | std::vector savedWidths; 106 | static std::unique_ptr widthBtnNode; 107 | static const Dim PEN_WIDTHS[]; 108 | }; 109 | 110 | class AutoAdjContainer; 111 | AutoAdjContainer* createPenToolbarAutoAdj(); 112 | -------------------------------------------------------------------------------- /syncscribble/resources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // translation fn 4 | extern "C" { 5 | const char* _(const char*); 6 | } 7 | class SvgCssStylesheet; 8 | 9 | void setupResources(); 10 | SvgCssStylesheet* createStylesheet(); 11 | bool setupI18n(const char* lc); 12 | -------------------------------------------------------------------------------- /syncscribble/rulingdialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ugui/widgets.h" 4 | #include "page.h" 5 | 6 | class ScribbleDoc; 7 | class ColorEditBox; 8 | 9 | class RulingDialog : public Dialog 10 | { 11 | public: 12 | RulingDialog(ScribbleDoc* doc); 13 | void accept(); 14 | 15 | static int predefSizes[][2]; 16 | static unsigned int predefRulings[][4]; 17 | 18 | private: 19 | void setPaperType(int index); 20 | void setRuleType(int index); 21 | void checkClipping(); 22 | 23 | ScribbleDoc* scribbleDoc; 24 | 25 | SpinBox* spinWidth; 26 | SpinBox* spinHeight; 27 | SpinBox* spinXRuling; 28 | SpinBox* spinYRuling; 29 | SpinBox* spinLeftMargin; 30 | ColorEditBox* pageColorPicker; 31 | ColorEditBox* ruleColorPicker; 32 | CheckBox* cbApplyToAll; 33 | CheckBox* cbDocDefault; 34 | CheckBox* cbGlobalDefault; 35 | ComboBox* comboRuling; 36 | ComboBox* comboPaperSize; 37 | Widget* clipWarning; 38 | ScrollWidget* scrollWidget = NULL; 39 | 40 | PageProperties props; 41 | }; 42 | -------------------------------------------------------------------------------- /syncscribble/scribbleconfig.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "basics.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "pugixml.hpp" 9 | #include "scribblepen.h" 10 | 11 | struct ltstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; } }; 12 | 13 | class ScribbleConfig { 14 | #ifdef SCRIBBLE_TEST 15 | friend class ScribbleTest; 16 | #endif 17 | private: 18 | // bools and ints 19 | std::map cfg; 20 | typedef std::map::const_iterator cfgIterator; 21 | // floats 22 | std::map cfgF; 23 | typedef std::map::const_iterator cfgFIterator; 24 | // strings 25 | std::map cfgS; 26 | typedef std::map::const_iterator cfgSIterator; 27 | 28 | ScribbleConfig* upconfig; 29 | 30 | public: 31 | ScribbleConfig(); 32 | ScribbleConfig(ScribbleConfig* _upconfig) : upconfig(_upconfig) {} 33 | void init(); 34 | ScribbleConfig* getUpConfig() { return upconfig != NULL ? upconfig : this; } 35 | bool loadConfig(const pugi::xml_node &cfgroot); 36 | void saveConfig(pugi::xml_node cfgroot, bool skipdefaults = false); 37 | bool loadConfigString(const char* cfgstr); 38 | bool loadConfigFile(const char* cfgfile); 39 | bool saveConfigFile(const char* cfgfile, bool skipdefaults = false); 40 | bool setConfigValue(const char* name, const char* val); 41 | 42 | ScribblePen* getPen(int num); 43 | void savePen(const ScribblePen& pen, int slot=-1); 44 | 45 | const char* isInt(const char* s) const; 46 | const char* isFloat(const char* s) const; 47 | const char* isString(const char* s) const; 48 | bool Bool(const char*, bool defaultval = false) const; 49 | int Int(const char*, int defaultval = 0) const; 50 | float Float(const char*, float defaultval = 0.0f) const; 51 | const char* String(const char* s, const char *defaultval = NULL) const; 52 | void set(const char* s, bool x); 53 | void set(const char* s, int x); 54 | void set(const char* s, unsigned int x) { set(s, int(x)); } 55 | void set(const char* s, float x); 56 | void set(const char* s, double x); 57 | void set(const char* s, const char* x); 58 | int removeInt(const char* s); 59 | int removeFloat(const char* s); 60 | int removeString(const char* s); 61 | 62 | // pens 63 | std::list pens; 64 | typedef std::list::iterator penIterator; 65 | }; 66 | -------------------------------------------------------------------------------- /syncscribble/scribbleinput.h: -------------------------------------------------------------------------------- 1 | #ifndef SCRIBBLEINPUT_H 2 | #define SCRIBBLEINPUT_H 3 | 4 | #include 5 | #include "basics.h" 6 | #include "ulib/geom.h" 7 | 8 | enum inputevent_t {INPUTEVENT_RELEASE=-1, INPUTEVENT_MOVE=0, INPUTEVENT_PRESS=1, INPUTEVENT_CANCEL=2, 9 | INPUTEVENT_NONE=3, INPUTEVENT_ENTER=4, INPUTEVENT_LEAVE=5}; 10 | enum inputsource_t {INPUTSOURCE_NONE=0, INPUTSOURCE_MOUSE=1, INPUTSOURCE_PEN=2, INPUTSOURCE_TOUCH=3}; 11 | enum inputmode_t {INPUTMODE_NONE=0, INPUTMODE_PAN=1, INPUTMODE_DRAW=2, INPUTMODE_ZOOM=2}; 12 | 13 | struct InputPoint { 14 | Dim x; 15 | Dim y; 16 | Dim pressure; 17 | Dim tiltX; 18 | Dim tiltY; 19 | inputevent_t event; 20 | //unsigned int id; 21 | 22 | InputPoint(inputevent_t _event, Dim _x = 0, Dim _y = 0, Dim _p = 1, Dim _tiltX = 0, Dim _tiltY = 0) 23 | : x(_x), y(_y), pressure(_p), tiltX(_tiltX), tiltY(_tiltY), event(_event) {} 24 | }; 25 | 26 | struct InputEvent { 27 | Timestamp t; 28 | int modemod; 29 | inputsource_t source; 30 | Point com; 31 | Dim maxTouchWidth; 32 | std::vector points; 33 | 34 | InputEvent(inputsource_t _source = INPUTSOURCE_NONE, int _modemod = 0, Timestamp _t = 0, Dim maxw = 0) 35 | : t(_t), modemod(_modemod), source(_source), maxTouchWidth(maxw) {} 36 | }; 37 | 38 | class ScribbleView; 39 | class ScribbleConfig; 40 | union SDL_Event; 41 | class SvgGui; 42 | 43 | class ScribbleInput 44 | { 45 | public: 46 | ScribbleView* parent; 47 | 48 | enum scribbling_t {NOT_SCRIBBLING=0, SCRIBBLING_PAN=1, SCRIBBLING_DRAW=3}; //SCRIBBLING_PANZOOM=2 49 | scribbling_t scribbling = NOT_SCRIBBLING; 50 | inputsource_t currInputSource = INPUTSOURCE_NONE; 51 | bool panning = false; 52 | int currModeMod = 0; 53 | int expectedPoints = 0; 54 | Timestamp lastEventTime = 0; 55 | bool enableHoverEvents = false; 56 | // for double clicking 57 | Point prevPointerCOM; 58 | Dim pointerPathLen = 0; 59 | Timestamp initPointerTime = 0; 60 | Point lastClickPos; 61 | Timestamp lastClickTime = 0; 62 | 63 | //Dim pressureScale = 1; 64 | Dim palmThreshold = 0; 65 | inputmode_t multiTouchMode; 66 | inputmode_t singleTouchMode; 67 | inputmode_t mouseMode; 68 | int singleTouchModeMod = 0; 69 | 70 | // The original value of DETECTED_PEN was 10; everytime we make changes that allow for more specific 71 | // pen detection, we should increment the value of DETECTED_PEN, which will result in detectPenType() 72 | // being rerun once after user installs update 73 | enum PenType {NO_PEN = 0, THINKPAD_PEN = 1, ICS_PEN = 2, SAMSUNG_PEN = 3, TEGRA_PEN = 4, 74 | REDETECT_PEN = 10, DETECTED_PEN = 11} penType; // FORCED_PEN = -1, 75 | 76 | static int pressedKey; 77 | static bool disableTouch; 78 | static bool simulatePenBtn; 79 | 80 | ScribbleInput(ScribbleView* _parent); 81 | void loadConfig(); 82 | void doInputEvent(Dim relx, Dim rely, Dim pressure, inputsource_t source, inputevent_t eventtype, int modemod, Timestamp t); 83 | bool isTouchAccepted(); 84 | void doInputEvent(InputEvent& event); 85 | void cancelAction(); //bool cancelpan = false); 86 | void forcePanMode(const InputEvent& event); 87 | bool sdlEvent(SvgGui* gui, SDL_Event* event); 88 | 89 | static Point pointerCOM(const std::vector& points); 90 | }; 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /syncscribble/scribblepen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "basics.h" 4 | #include "ulib/painter.h" 5 | 6 | class ScribblePen 7 | { 8 | public: 9 | Color color; 10 | Dim width; 11 | Dim wRatio; // (maxwidth - minwidth)/maxwidth 12 | Dim prParam; 13 | Dim spdMax; 14 | Dim dirAngle; 15 | Dim dash, gap; 16 | 17 | unsigned int flags; 18 | // existing numerical values must NOT be changed - flags is serialized to config file when saving pen 19 | static constexpr unsigned int DRAW_UNDER = 0x1, SNAP_TO_GRID = 0x2, LINE_DRAWING = 0x4, EPHEMERAL = 0x8, 20 | WIDTH_PR = 0x10, WIDTH_SPEED = 0x20, WIDTH_DIR = 0x40, WIDTH_MASK = 0xF0, //WIDTH_LINPR = 0x80, 21 | TIP_FLAT = 0x100, TIP_ROUND = 0x200, TIP_CHISEL = 0x400, TIP_MASK = 0xF00; 22 | 23 | ScribblePen(Color c, Dim w, unsigned int _flags = 0, Dim wr = 0, Dim pr = 0, Dim spd = 0, Dim angle = 0, Dim _dash = 0, Dim _gap = 0) 24 | : color(c), width(w), wRatio(wr), prParam(pr), spdMax(spd), dirAngle(angle), dash(_dash), gap(_gap), flags(_flags) {} 25 | 26 | bool operator==(const ScribblePen& b) const { return memcmp(this, &b, sizeof(ScribblePen)) == 0; } 27 | 28 | bool hasFlag(unsigned int flag) const { return (flags & flag) == flag; } 29 | void setFlag(unsigned int flag, bool value) { if(value) flags |= flag; else flags &= ~flag; } 30 | void clearAndSet(unsigned int clearflag, unsigned int setflag) { flags = (flags & ~clearflag) | setflag; } 31 | bool hasVarWidth() const { return flags & WIDTH_MASK; } 32 | bool usesPressure() const { return hasFlag(WIDTH_PR); } 33 | 34 | Rect getBBox() const 35 | { 36 | Dim hw = 0.75*0.5*width; //pressureparam > 0 ? 0.5*width * (1 - pow(1 - 0.66, pressureparam)) : 0.5*width; 37 | return Rect::ltrb(-hw, -hw, hw, hw); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /syncscribble/scribblewidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "basics.h" 4 | #include "ugui/svggui.h" 5 | 6 | class TextBox; 7 | class Button; 8 | class ScribbleView; 9 | 10 | class ScribbleWidget : public Widget 11 | { 12 | public: 13 | ScribbleWidget(ScribbleView* sv); 14 | void setScroller(Widget* s, Widget* scrollind); 15 | 16 | void draw(SvgPainter* svgp) const override; 17 | Rect bounds(SvgPainter* svgp) const override; 18 | Rect dirtyRect() const override; 19 | 20 | void startTimer(Dim periodMs); 21 | void setScrollPosition(Dim pos, Dim vfrac); 22 | void showScroller(); 23 | 24 | ScribbleView* scribbleView; 25 | Widget* scroller = NULL; 26 | Widget* scrollIndicator = NULL; 27 | Timer* scrollerFadeTimer = NULL; 28 | Dim prevScrollerY = 0; 29 | 30 | TextBox* pageNumLabel = NULL; 31 | TextBox* fileNameLabel = NULL; 32 | TextBox* timeRangeLabel = NULL; 33 | TextBox* zoomLabel = NULL; 34 | Widget* focusIndicator = NULL; 35 | Button* nextPage = NULL; 36 | Button* prevPage = NULL; 37 | 38 | // needed to access private members of ScribbleView 39 | static ScribbleWidget* create(Widget* container, ScribbleView* area); 40 | }; 41 | 42 | class Selection; 43 | class ScribbleArea; 44 | 45 | class OverlayWidget : public Widget 46 | { 47 | public: 48 | OverlayWidget(Widget* under); 49 | void drawSelection(Selection* sel, Point gpos = Point(), Point dr = Point(), Dim s = 1); 50 | bool canDrop(Point gpos) const { return getScribbleArea(gpos) != NULL; } 51 | bool dropSelection(Selection* clip, Point gpos, Point dr, bool replaceids = false); 52 | 53 | Rect bounds(SvgPainter* svgp) const override; 54 | void draw(SvgPainter* svgp) const override; 55 | Rect dirtyRect() const override { return currSelBounds.united(renderedSelBounds); } 56 | 57 | private: 58 | ScribbleArea* getScribbleArea(Point gpos) const; 59 | 60 | Widget* underWidget; 61 | Selection* selection; 62 | Point globalPos; 63 | Point offset; 64 | Dim scale; 65 | Rect m_bounds; 66 | Rect m_dirty; 67 | Rect currSelBounds; 68 | mutable Rect renderedSelBounds; 69 | }; 70 | -------------------------------------------------------------------------------- /syncscribble/syncdialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ugui/widgets.h" 4 | #include "ugui/textedit.h" 5 | 6 | class ScribbleSync; 7 | 8 | class SyncLoginDialog : public Dialog 9 | { 10 | public: 11 | SyncLoginDialog(const char* username, bool savepw, const char* msg); 12 | 13 | TextEdit* userEdit = NULL; 14 | TextEdit* passEdit = NULL; 15 | CheckBox* savePassword = NULL; 16 | }; 17 | 18 | class SyncCreateDialog : public Dialog 19 | { 20 | public: 21 | SyncCreateDialog(const char* url, const char* title, bool showLink); 22 | void setMessage(const char* msg); 23 | 24 | TextEdit* urlEdit = NULL; 25 | TextEdit* titleEdit = NULL; 26 | CheckBox* lectureMode = NULL; 27 | TextBox* msgLabel = NULL; 28 | Button* linkBtn = NULL; 29 | }; 30 | 31 | class SyncOpenDialog : public Dialog 32 | { 33 | public: 34 | SyncOpenDialog(bool showLink); 35 | void setMessage(const char* msg); 36 | 37 | TextEdit* urlEdit = NULL; 38 | TextBox* msgLabel = NULL; 39 | Button* linkBtn = NULL; 40 | }; 41 | 42 | class SyncInfoDialog : public Dialog 43 | { 44 | public: 45 | SyncInfoDialog(const ScribbleSync* sync); 46 | 47 | TextEdit* urlEdit = NULL; 48 | }; 49 | -------------------------------------------------------------------------------- /syncscribble/touchwidgets.h: -------------------------------------------------------------------------------- 1 | #ifndef TOUCHWIDGETS_H 2 | #define TOUCHWIDGETS_H 3 | 4 | #include "ugui/widgets.h" 5 | #include "ugui/colorwidgets.h" 6 | #include "scribblepen.h" 7 | 8 | class ScribbleApp; 9 | 10 | class PenPreview : public Widget 11 | { 12 | public: 13 | PenPreview(); //int n = -1); 14 | void setPen(const ScribblePen& pen) { mPen = pen; redraw(); } 15 | // assuming this is derived from SvgNodeLayout, we have access to layout transform and so can use it to set 16 | // canvas size instead of scaling what we draw 17 | void draw(SvgPainter* svgp) const override; 18 | Rect bounds(SvgPainter* svgp) const override; 19 | 20 | Rect mBounds; 21 | static Color bgColor; 22 | private: 23 | //int penNum; 24 | ScribblePen mPen = {Color::INVALID_COLOR, -1}; 25 | }; 26 | 27 | // this is Widget for the actual dial canvas; toolbutton is just a regular toolbutton with special sdlEvent handler 28 | class ButtonDragDial : public AbsPosWidget 29 | { 30 | public: 31 | ButtonDragDial(Button* tb); 32 | //~ButtonDragDial(); 33 | 34 | void draw(SvgPainter* svgp) const override; 35 | Rect bounds(SvgPainter* svgp) const override; 36 | 37 | // These should of course be private 38 | std::function onStep; 39 | std::function onAltStep; 40 | 41 | private: 42 | double posToAngle(const Point& pos); 43 | void updateDial(Dim angle, bool active, int count); 44 | 45 | Button* toolBtn; 46 | Rect mBounds; 47 | //int yCenter; 48 | 49 | double stepAngle; 50 | double indAngle; 51 | bool indActive; 52 | int indCount; 53 | double prevAngle; 54 | bool dialMoved; 55 | bool altMode; 56 | }; 57 | 58 | class Menubar : public Toolbar 59 | { 60 | public: 61 | Menubar(SvgNode* n); 62 | void addButton(Button* btn); 63 | Button* addAction(Action* action); 64 | 65 | bool autoClose = false; 66 | }; 67 | 68 | Menubar* createMenubar(); 69 | Menubar* createVertMenubar(); 70 | 71 | class AutoAdjContainer : public Widget 72 | { 73 | public: 74 | AutoAdjContainer(SvgNode* n, Widget* _contents); 75 | void repeatLayout(const Rect& dest); 76 | 77 | std::function adjFn; 78 | Widget* contents; 79 | Rect contentsBBox; 80 | 81 | //private: 82 | // int numAbsPos = 0; 83 | }; 84 | 85 | // tooltip for widget with long press/right click action 86 | #define altTooltip(s1, s2) fstring("%s\n%s", s1, s2).c_str() 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /syncscribble/wasm/wasmhelper.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "emscripten.h" 3 | #include "emscripten/html5.h" 4 | #include "ugui/svggui_platform.h" 5 | 6 | // Refs: 7 | // - www.w3.org/TR/pointerevents/ 8 | // - emscripten.org/docs/ 9 | 10 | // neither Chrome nor Firefox appear to access ptHimetricLocation anywhere, and thus do not support subpixel 11 | // resolution on Windows, even though x,y were changed from int to float 12 | 13 | void emPtrEvent(const char* device, int evtype, int ptrid, int buttons, double x, double y, double pr, double t) 14 | { 15 | static int mouseBtns = 0; 16 | SDL_Event event = {0}; 17 | if(strcmp(device, "pen") == 0) { 18 | event.tfinger.touchId = buttons & 32 ? PenPointerEraser : PenPointerPen; 19 | event.tfinger.fingerId = buttons; 20 | } 21 | else if(strcmp(device, "touch") == 0) { 22 | event.tfinger.touchId = 0; 23 | event.tfinger.fingerId = ptrid; 24 | } 25 | else if(strcmp(device, "mouse") == 0) { 26 | // swap bits 1 and 2 (if they are different) - middle button / right button 27 | if((buttons & 0x6) == 0x4 || (buttons & 0x6) == 0x2) 28 | buttons ^= 0x6; 29 | event.tfinger.touchId = SDL_TOUCH_MOUSEID; 30 | event.tfinger.fingerId = (evtype == 1) ? buttons : (buttons ^ mouseBtns); 31 | mouseBtns = buttons; 32 | } 33 | else 34 | return; 35 | 36 | event.type = evtype == 1 ? SDL_FINGERDOWN : (evtype == -1 ? SDL_FINGERUP : SDL_FINGERMOTION); 37 | event.tfinger.x = x; 38 | event.tfinger.y = y; 39 | //event.tfinger.dx = tiltX; // use dx, dy for tilt 40 | //event.tfinger.dy = tiltY; 41 | event.tfinger.pressure = pr; 42 | event.tfinger.timestamp = t > 0 ? t : SDL_GetTicks(); 43 | // PeepEvents bypasses gesture recognizer and event filters 44 | SDL_PeepEvents(&event, 1, SDL_ADDEVENT, 0, 0); 45 | } 46 | 47 | EM_JS(void, jsSetupPtrEvents, (), 48 | { 49 | const emPtrEvent = Module.cwrap('emPtrEvent', 50 | null, ['string', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); 51 | const ptrevent = function(ev, evtype) { 52 | //console.log(ev); 53 | if(evtype == 0 && typeof ev.getCoalescedEvents === "function") { // only for move events 54 | const evs = ev.getCoalescedEvents(); 55 | //console.log(evs); 56 | for(const e of evs) { 57 | emPtrEvent(e.pointerType, evtype, e.pointerId, e.buttons, e.clientX, e.clientY, e.pressure, e.timeStamp); 58 | } 59 | } 60 | else { 61 | emPtrEvent(ev.pointerType, evtype, ev.pointerId, ev.buttons, ev.clientX, ev.clientY, ev.pressure, ev.timeStamp); 62 | } 63 | }; 64 | 65 | var el = document.getElementById("canvas"); 66 | // Register pointer event handlers 67 | el.onpointerdown = function(ev) { ptrevent(ev, 1); }; 68 | el.onpointermove = function(ev) { ptrevent(ev, 0); }; 69 | el.onpointerup = function(ev) { ptrevent(ev, -1); }; 70 | el.onpointercancel = function(ev) { ptrevent(ev, -1); }; 71 | }); 72 | 73 | void wasmSetupInput() 74 | { 75 | emscripten_set_mousemove_callback("#canvas", NULL, 0, NULL); 76 | emscripten_set_mousedown_callback("#canvas", NULL, 0, NULL); 77 | emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL); 78 | emscripten_set_touchstart_callback("#canvas", NULL, 0, NULL); 79 | emscripten_set_touchend_callback("#canvas", NULL, 0, NULL); 80 | emscripten_set_touchmove_callback("#canvas", NULL, 0, NULL); 81 | emscripten_set_touchcancel_callback("#canvas", NULL, 0, NULL); 82 | jsSetupPtrEvents(); 83 | } 84 | -------------------------------------------------------------------------------- /syncscribble/wasm/wasmhelper.h: -------------------------------------------------------------------------------- 1 | #ifndef WASMHELPER_H 2 | #define WASMHELPER_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | extern void wasmSetupInput(); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /syncscribble/windows/InstallWrite.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 1 53 | 1 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /syncscribble/windows/plain.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/syncscribble/windows/plain.ico -------------------------------------------------------------------------------- /syncscribble/windows/resources.rc: -------------------------------------------------------------------------------- 1 | // since IDI_ICON1, etc. aren't defined in a resource.h, I think they'll just be treated as strings 2 | IDI_ICON1 ICON "write.ico" 3 | IDI_ICON2 ICON "ruled.ico" 4 | 5 | #include 6 | 7 | VS_VERSION_INFO VERSIONINFO 8 | FILEVERSION VERSIONCSV 9 | PRODUCTVERSION VERSIONCSV 10 | BEGIN 11 | BLOCK "StringFileInfo" 12 | BEGIN 13 | BLOCK "040904E4" 14 | BEGIN 15 | VALUE "CompanyName", "Stylus Labs" 16 | VALUE "FileDescription", "Write" 17 | VALUE "FileVersion", VERSIONSTR 18 | VALUE "InternalName", "Write" 19 | VALUE "LegalCopyright", "Copyright 2020 Stylus Labs" 20 | VALUE "OriginalFilename", "write.exe" 21 | VALUE "ProductName", "Write" 22 | VALUE "ProductVersion", VERSIONSTR 23 | END 24 | END 25 | 26 | BLOCK "VarFileInfo" 27 | BEGIN 28 | VALUE "Translation", 0x409, 1252 29 | END 30 | END 31 | -------------------------------------------------------------------------------- /syncscribble/windows/ruled.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/syncscribble/windows/ruled.ico -------------------------------------------------------------------------------- /syncscribble/windows/winhelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define WIN32_LEAN_AND_MEAN 3 | #include 4 | 5 | #include "ugui/svggui.h" 6 | 7 | void initTouchInput(SDL_Window* sdlwin, bool useWintab); 8 | //bool touchInputFilter(SDL_Event* event); 9 | void setDPIAware(); 10 | Image getClipboardImage(); 11 | -------------------------------------------------------------------------------- /syncscribble/windows/wintab/MSGPACK.H: -------------------------------------------------------------------------------- 1 | /* ------------------------------- msgpack.h -------------------------------- */ 2 | /*------------------------------------------------------------------------------ 3 | Selected message unpacking macros from windowsx.h 4 | to circumvent compile-time memory headaches. 5 | 6 | The text and information contained in this file may be freely used, 7 | copied, or distributed without compensation or licensing restrictions. 8 | 9 | This file is Copyright (c) Wacom Company, Ltd. 2010 All Rights Reserved 10 | with portions copyright 1991-1998 by LCS/Telegraphics. 11 | ------------------------------------------------------------------------------*/ 12 | #ifdef WIN32 13 | #define GET_WM_ACTIVATE_STATE(wp, lp) LOWORD(wp) 14 | #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp) 15 | #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp) 16 | #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp) 17 | #define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) \ 18 | (void)(fn)((hwnd), WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl)) 19 | /* -------------------------------------------------------------------------- */ 20 | #else 21 | #define GET_WM_ACTIVATE_STATE(wp, lp) (wp) 22 | #define GET_WM_COMMAND_ID(wp, lp) (wp) 23 | #define GET_WM_COMMAND_HWND(wp, lp) (HWND)LOWORD(lp) 24 | #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(lp) 25 | #define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) \ 26 | (void)(fn)((hwnd), WM_COMMAND, (WPARAM)(int)(id), MAKELPARAM((UINT)(hwndCtl), (codeNotify))) 27 | /* -------------------------------------------------------------------------- */ 28 | #endif 29 | -------------------------------------------------------------------------------- /syncscribble/windows/wintab/Utils.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------- 2 | 3 | NAME 4 | Utils.h 5 | 6 | PURPOSE 7 | Defines for the general-purpose functions for the WinTab demos. 8 | 9 | COPYRIGHT 10 | Copyright (c) Wacom Company, Ltd. 2010 All Rights Reserved 11 | All rights reserved. 12 | 13 | ---------------------------------------------------------------------------- */ 14 | #pragma once 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "wintab.h" // NOTE: get from wactab header package 26 | 27 | 28 | ////////////////////////////////////////////////////////////////////////////// 29 | //#define WACOM_DEBUG 30 | 31 | // Ignore warnings about using unsafe string functions. 32 | //#pragma warning( disable : 4996 ) 33 | 34 | ////////////////////////////////////////////////////////////////////////////// 35 | // Function pointers to Wintab functions exported from wintab32.dll. 36 | typedef UINT ( API * WTINFOA ) ( UINT, UINT, LPVOID ); 37 | typedef HCTX ( API * WTOPENA )( HWND, LPLOGCONTEXTA, BOOL ); 38 | typedef BOOL ( API * WTGETA ) ( HCTX, LPLOGCONTEXTA ); 39 | typedef BOOL ( API * WTSETA ) ( HCTX, LPLOGCONTEXTA ); 40 | typedef BOOL ( API * WTCLOSE ) ( HCTX ); 41 | typedef BOOL ( API * WTENABLE ) ( HCTX, BOOL ); 42 | typedef BOOL ( API * WTPACKET ) ( HCTX, UINT, LPVOID ); 43 | typedef BOOL ( API * WTOVERLAP ) ( HCTX, BOOL ); 44 | typedef BOOL ( API * WTSAVE ) ( HCTX, LPVOID ); 45 | typedef BOOL ( API * WTCONFIG ) ( HCTX, HWND ); 46 | typedef HCTX ( API * WTRESTORE ) ( HWND, LPVOID, BOOL ); 47 | typedef BOOL ( API * WTEXTSET ) ( HCTX, UINT, LPVOID ); 48 | typedef BOOL ( API * WTEXTGET ) ( HCTX, UINT, LPVOID ); 49 | typedef BOOL ( API * WTQUEUESIZESET ) ( HCTX, int ); 50 | typedef int ( API * WTDATAPEEK ) ( HCTX, UINT, UINT, int, LPVOID, LPINT); 51 | typedef int ( API * WTPACKETSGET ) (HCTX, int, LPVOID); 52 | 53 | // TODO - add more wintab32 function defs as needed 54 | 55 | ////////////////////////////////////////////////////////////////////////////// 56 | //extern char* gpszProgramName; 57 | 58 | // Loaded Wintab32 API functions. 59 | extern HINSTANCE ghWintab; 60 | 61 | extern WTINFOA gpWTInfoA; 62 | extern WTOPENA gpWTOpenA; 63 | extern WTGETA gpWTGetA; 64 | extern WTSETA gpWTSetA; 65 | extern WTCLOSE gpWTClose; 66 | extern WTPACKET gpWTPacket; 67 | extern WTENABLE gpWTEnable; 68 | extern WTOVERLAP gpWTOverlap; 69 | extern WTSAVE gpWTSave; 70 | extern WTCONFIG gpWTConfig; 71 | extern WTRESTORE gpWTRestore; 72 | extern WTEXTSET gpWTExtSet; 73 | extern WTEXTGET gpWTExtGet; 74 | extern WTQUEUESIZESET gpWTQueueSizeSet; 75 | extern WTDATAPEEK gpWTDataPeek; 76 | extern WTPACKETSGET gpWTPacketsGet; 77 | 78 | // TODO - add more wintab32 function pointers as needed 79 | 80 | ////////////////////////////////////////////////////////////////////////////// 81 | BOOL LoadWintab( void ); 82 | void UnloadWintab( void ); 83 | 84 | ////////////////////////////////////////////////////////////////////////////// 85 | #ifdef WACOM_DEBUG 86 | 87 | void ShowError( char *pszErrorMessage ); 88 | void WacomTrace( char *lpszFormat, ...); 89 | 90 | #define WACOM_ASSERT( x ) assert( x ) 91 | #define WACOM_TRACE(...) WacomTrace(__VA_ARGS__) 92 | #else 93 | #define WACOM_TRACE(...) 94 | #define WACOM_ASSERT( x ) 95 | 96 | #endif // WACOM_DEBUG 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | -------------------------------------------------------------------------------- /syncscribble/windows/write.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/syncscribble/windows/write.ico -------------------------------------------------------------------------------- /xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png -------------------------------------------------------------------------------- /xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png -------------------------------------------------------------------------------- /xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png -------------------------------------------------------------------------------- /xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon76x76@2x.png -------------------------------------------------------------------------------- /xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/AppIcon83.5x83.5@2x.png -------------------------------------------------------------------------------- /xcode/Write/Write/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "AppIcon60x60@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "AppIcon60x60@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "20x20", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "20x20", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "idiom" : "ipad", 57 | "size" : "29x29", 58 | "scale" : "1x" 59 | }, 60 | { 61 | "idiom" : "ipad", 62 | "size" : "29x29", 63 | "scale" : "2x" 64 | }, 65 | { 66 | "idiom" : "ipad", 67 | "size" : "40x40", 68 | "scale" : "1x" 69 | }, 70 | { 71 | "idiom" : "ipad", 72 | "size" : "40x40", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "76x76", 77 | "idiom" : "ipad", 78 | "scale" : "1x" 79 | }, 80 | { 81 | "size" : "76x76", 82 | "idiom" : "ipad", 83 | "filename" : "AppIcon76x76@2x.png", 84 | "scale" : "2x" 85 | }, 86 | { 87 | "size" : "83.5x83.5", 88 | "idiom" : "ipad", 89 | "filename" : "AppIcon83.5x83.5@2x.png", 90 | "scale" : "2x" 91 | }, 92 | { 93 | "size" : "1024x1024", 94 | "idiom" : "ios-marketing", 95 | "filename" : "AppIcon1024x1024.png", 96 | "scale" : "1x" 97 | } 98 | ], 99 | "info" : { 100 | "version" : 1, 101 | "author" : "xcode" 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /xcode/Write/Write/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /xcode/Write/Write/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /xcode/Write/Write/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/Write/Write/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /xcode/Write/Write/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /xcode/Write/Write/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Write 9 | CFBundleDocumentTypes 10 | 11 | 12 | CFBundleTypeName 13 | public.svg-image 14 | CFBundleTypeRole 15 | Editor 16 | LSHandlerRank 17 | Default 18 | LSItemContentTypes 19 | 20 | public.svg-image 21 | 22 | 23 | 24 | CFBundleExecutable 25 | Write 26 | CFBundleIcons 27 | 28 | CFBundlePrimaryIcon 29 | 30 | CFBundleIconFiles 31 | 32 | AppIcon60x60 33 | 34 | CFBundleIconName 35 | AppIcon 36 | 37 | 38 | CFBundleIcons~ipad 39 | 40 | CFBundlePrimaryIcon 41 | 42 | CFBundleIconFiles 43 | 44 | AppIcon60x60 45 | AppIcon76x76 46 | 47 | CFBundleIconName 48 | AppIcon 49 | 50 | 51 | CFBundleIdentifier 52 | com.styluslabs.write3 53 | CFBundleInfoDictionaryVersion 54 | 6.0 55 | CFBundleName 56 | Write 57 | CFBundlePackageType 58 | APPL 59 | CFBundleShortVersionString 60 | $(MARKETING_VERSION) 61 | CFBundleSupportedPlatforms 62 | 63 | iPhoneOS 64 | 65 | CFBundleVersion 66 | $(CURRENT_PROJECT_VERSION) 67 | ITSAppUsesNonExemptEncryption 68 | 69 | LSRequiresIPhoneOS 70 | 71 | LSSupportsOpeningDocumentsInPlace 72 | 73 | NSPhotoLibraryAddUsageDescription 74 | Write can save an image of the document to your photo library for easy sharing. 75 | UIFileSharingEnabled 76 | 77 | UILaunchStoryboardName 78 | LaunchView 79 | UIRequiredDeviceCapabilities 80 | 81 | arm64 82 | metal 83 | opengles-3 84 | 85 | UISupportedInterfaceOrientations 86 | 87 | UIInterfaceOrientationPortrait 88 | UIInterfaceOrientationPortraitUpsideDown 89 | UIInterfaceOrientationLandscapeLeft 90 | UIInterfaceOrientationLandscapeRight 91 | 92 | UISupportsDocumentBrowser 93 | 94 | UIViewControllerBasedStatusBarAppearance 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /xcode/Write/Write/LaunchView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /xcode/Write/Write/dummy.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // dummy.c 3 | // Write 4 | // 5 | // Created by mwhite on 3/3/20. 6 | // Copyright © 2020 mwhite. All rights reserved. 7 | // 8 | 9 | bool xcode_build_dummy = true; 10 | -------------------------------------------------------------------------------- /xcode/Write/Write/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Write 4 | // 5 | // Created by mwhite on 1/5/20. 6 | // Copyright © 2020 mwhite. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | NSString * appDelegateClassName; 14 | @autoreleasepool { 15 | // Setup code that might create autoreleased objects goes here. 16 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 17 | } 18 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 19 | } 20 | -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon1024x1024.png -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@2x.png -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon60x60@3x.png -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon76x76@2x.png -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/AppIcon83.5x83.5@2x.png -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "AppIcon60x60@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "AppIcon60x60@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "20x20", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "20x20", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "idiom" : "ipad", 57 | "size" : "29x29", 58 | "scale" : "1x" 59 | }, 60 | { 61 | "idiom" : "ipad", 62 | "size" : "29x29", 63 | "scale" : "2x" 64 | }, 65 | { 66 | "idiom" : "ipad", 67 | "size" : "40x40", 68 | "scale" : "1x" 69 | }, 70 | { 71 | "idiom" : "ipad", 72 | "size" : "40x40", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "76x76", 77 | "idiom" : "ipad", 78 | "scale" : "1x" 79 | }, 80 | { 81 | "size" : "76x76", 82 | "idiom" : "ipad", 83 | "filename" : "AppIcon76x76@2x.png", 84 | "scale" : "2x" 85 | }, 86 | { 87 | "size" : "83.5x83.5", 88 | "idiom" : "ipad", 89 | "filename" : "AppIcon83.5x83.5@2x.png", 90 | "scale" : "2x" 91 | }, 92 | { 93 | "size" : "1024x1024", 94 | "idiom" : "ios-marketing", 95 | "filename" : "AppIcon1024x1024.png", 96 | "scale" : "1x" 97 | } 98 | ], 99 | "info" : { 100 | "version" : 1, 101 | "author" : "xcode" 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/styluslabs/Write/2c3ebcff6034b413889a4947058cef19d8c1d363/xcode/WriteIAP/Write/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Write 9 | CFBundleDocumentTypes 10 | 11 | 12 | CFBundleTypeName 13 | public.svg-image 14 | CFBundleTypeRole 15 | Editor 16 | LSHandlerRank 17 | Default 18 | LSItemContentTypes 19 | 20 | public.svg-image 21 | 22 | 23 | 24 | CFBundleExecutable 25 | Write 26 | CFBundleIcons 27 | 28 | CFBundlePrimaryIcon 29 | 30 | CFBundleIconFiles 31 | 32 | AppIcon60x60 33 | 34 | CFBundleIconName 35 | AppIcon 36 | 37 | 38 | CFBundleIcons~ipad 39 | 40 | CFBundlePrimaryIcon 41 | 42 | CFBundleIconFiles 43 | 44 | AppIcon60x60 45 | AppIcon76x76 46 | 47 | CFBundleIconName 48 | AppIcon 49 | 50 | 51 | CFBundleIdentifier 52 | $(PRODUCT_BUNDLE_IDENTIFIER) 53 | CFBundleInfoDictionaryVersion 54 | 6.0 55 | CFBundleName 56 | Write 57 | CFBundlePackageType 58 | APPL 59 | CFBundleShortVersionString 60 | $(MARKETING_VERSION) 61 | CFBundleSupportedPlatforms 62 | 63 | iPhoneOS 64 | 65 | CFBundleVersion 66 | $(CURRENT_PROJECT_VERSION) 67 | ITSAppUsesNonExemptEncryption 68 | 69 | LSRequiresIPhoneOS 70 | 71 | LSSupportsOpeningDocumentsInPlace 72 | 73 | NSPhotoLibraryAddUsageDescription 74 | Write can save an image of the document to your photo library for easy sharing. 75 | UIFileSharingEnabled 76 | 77 | UILaunchStoryboardName 78 | LaunchView 79 | UIRequiredDeviceCapabilities 80 | 81 | arm64 82 | metal 83 | opengles-3 84 | 85 | UISupportedInterfaceOrientations 86 | 87 | UIInterfaceOrientationPortrait 88 | UIInterfaceOrientationPortraitUpsideDown 89 | UIInterfaceOrientationLandscapeLeft 90 | UIInterfaceOrientationLandscapeRight 91 | 92 | UISupportsDocumentBrowser 93 | 94 | UIViewControllerBasedStatusBarAppearance 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/LaunchView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/dummy.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // dummy.c 3 | // Write 4 | // 5 | // Created by mwhite on 3/3/20. 6 | // Copyright © 2020 mwhite. All rights reserved. 7 | // 8 | 9 | bool xcode_build_dummy = true; 10 | -------------------------------------------------------------------------------- /xcode/WriteIAP/Write/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Write 4 | // 5 | // Created by mwhite on 1/5/20. 6 | // Copyright © 2020 mwhite. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | NSString * appDelegateClassName; 14 | @autoreleasepool { 15 | // Setup code that might create autoreleased objects goes here. 16 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 17 | } 18 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 19 | } 20 | --------------------------------------------------------------------------------