Merge branch 'stroke-improvements' into 1.4-dev

Adds (experimental) stroke simplification methods
preferencesAboutTextFull
Craig Watson 8 years ago
commit 0bf8c58235
  1. 407
      resources/forms/brushProperties.ui
  2. 2
      src/core/UBPreferencesController.cpp
  3. 2
      src/core/UBSettings.cpp
  4. 2
      src/core/UBSettings.h
  5. 120
      src/domain/UBGraphicsScene.cpp
  6. 5
      src/domain/UBGraphicsScene.h
  7. 76
      src/domain/UBGraphicsStroke.cpp
  8. 13
      src/domain/UBGraphicsStroke.h
  9. 105
      src/frameworks/UBGeometryUtils.cpp
  10. 1
      src/frameworks/UBGeometryUtils.h
  11. 53
      src/frameworks/UBInterpolator.cpp
  12. 45
      src/frameworks/UBInterpolator.h
  13. 6
      src/frameworks/frameworks.pri

@ -1,7 +1,8 @@
<ui version="4.0" > <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>brushProperties</class> <class>brushProperties</class>
<widget class="QFrame" name="brushProperties" > <widget class="QFrame" name="brushProperties">
<property name="geometry" > <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
@ -9,25 +10,25 @@
<height>808</height> <height>808</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle">
<string/> <string/>
</property> </property>
<property name="frameShape" > <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Plain</enum> <enum>QFrame::Plain</enum>
</property> </property>
<layout class="QGridLayout" name="gridLayout" > <layout class="QGridLayout" name="gridLayout">
<item row="0" column="1" > <item row="0" column="1">
<spacer name="nSpacer" > <spacer name="nSpacer">
<property name="orientation" > <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType" > <property name="sizeType">
<enum>QSizePolicy::Fixed</enum> <enum>QSizePolicy::Fixed</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>40</height> <height>40</height>
@ -35,53 +36,40 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="1" column="0" > <item row="1" column="1">
<spacer name="nwSpacer" > <widget class="QFrame" name="colorFrame">
<property name="orientation" > <property name="frameShape">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" >
<widget class="QFrame" name="colorFrame" >
<property name="frameShape" >
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout" > <layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing" > <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QFrame" name="lightBackgroundFrame" > <widget class="QFrame" name="lightBackgroundFrame">
<property name="frameShape" > <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QHBoxLayout" name="lightBackgroundLayout" > <layout class="QHBoxLayout" name="lightBackgroundLayout">
<item> <item>
<widget class="QLabel" name="lightBackgroundLabel" > <widget class="QLabel" name="lightBackgroundLabel">
<property name="text" > <property name="text">
<string>On Light Background</string> <string>On Light Background</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer" > <spacer name="horizontalSpacer">
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>40</width>
<height>20</height> <height>20</height>
@ -90,17 +78,17 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="UBColorPicker" name="lightBackgroundColorPicker0" > <widget class="UBColorPicker" name="lightBackgroundColorPicker0">
<property name="minimumSize" > <property name="minimumSize">
<size> <size>
<width>32</width> <width>32</width>
<height>32</height> <height>32</height>
</size> </size>
</property> </property>
<property name="frameShape" > <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
</widget> </widget>
@ -109,27 +97,27 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QFrame" name="darkBackgroundFrame" > <widget class="QFrame" name="darkBackgroundFrame">
<property name="frameShape" > <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QHBoxLayout" name="darkBackgroundLayout" > <layout class="QHBoxLayout" name="darkBackgroundLayout">
<item> <item>
<widget class="QLabel" name="darkBackgroundLabel" > <widget class="QLabel" name="darkBackgroundLabel">
<property name="text" > <property name="text">
<string>On Dark Background</string> <string>On Dark Background</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_2" > <spacer name="horizontalSpacer_2">
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>40</width>
<height>20</height> <height>20</height>
@ -138,17 +126,17 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="UBColorPicker" name="darkBackgroundColorPicker0" > <widget class="UBColorPicker" name="darkBackgroundColorPicker0">
<property name="minimumSize" > <property name="minimumSize">
<size> <size>
<width>32</width> <width>32</width>
<height>32</height> <height>32</height>
</size> </size>
</property> </property>
<property name="frameShape" > <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
</widget> </widget>
@ -159,34 +147,21 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="2" > <item row="2" column="0" colspan="3">
<spacer name="neSpacer" > <widget class="QFrame" name="opacityFrame">
<property name="orientation" > <property name="frameShape">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="3" >
<widget class="QFrame" name="opacityFrame" >
<property name="frameShape" >
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout" > <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<spacer name="wSpacer_2" > <spacer name="wSpacer_2">
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>154</width> <width>154</width>
<height>20</height> <height>20</height>
@ -195,40 +170,40 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QLabel" name="opacityLabel" > <widget class="QLabel" name="opacityLabel">
<property name="text" > <property name="text">
<string>Opacity</string> <string>Opacity</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QSlider" name="opacitySlider" > <widget class="QSlider" name="opacitySlider">
<property name="minimum" > <property name="minimum">
<number>20</number> <number>20</number>
</property> </property>
<property name="maximum" > <property name="maximum">
<number>100</number> <number>100</number>
</property> </property>
<property name="value" > <property name="value">
<number>50</number> <number>50</number>
</property> </property>
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="tickPosition" > <property name="tickPosition">
<enum>QSlider::TicksAbove</enum> <enum>QSlider::TicksAbove</enum>
</property> </property>
<property name="tickInterval" > <property name="tickInterval">
<number>20</number> <number>20</number>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="eSpacer_2" > <spacer name="eSpacer_2">
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>156</width> <width>156</width>
<height>20</height> <height>20</height>
@ -239,40 +214,27 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="1" > <item row="4" column="0" colspan="3">
<spacer name="cSpacer" > <widget class="QGroupBox" name="lineWidthGroupBox">
<property name="orientation" > <property name="sizePolicy">
<enum>Qt::Vertical</enum> <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="3" >
<widget class="QGroupBox" name="lineWidthGroupBox" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="title" > <property name="title">
<string>Line Width</string> <string>Line Width</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2" > <layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1" > <item row="1" column="1">
<spacer name="wSpacer" > <spacer name="wSpacer">
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeType" > <property name="sizeType">
<enum>QSizePolicy::Fixed</enum> <enum>QSizePolicy::Fixed</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>40</width>
<height>20</height> <height>20</height>
@ -280,15 +242,15 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="1" column="3" > <item row="1" column="3">
<spacer name="eSpacer" > <spacer name="eSpacer">
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeType" > <property name="sizeType">
<enum>QSizePolicy::Fixed</enum> <enum>QSizePolicy::Fixed</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>40</width>
<height>20</height> <height>20</height>
@ -296,149 +258,149 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="1" column="2" > <item row="1" column="2">
<widget class="QSlider" name="fineSlider" > <widget class="QSlider" name="fineSlider">
<property name="minimum" > <property name="minimum">
<number>5</number> <number>5</number>
</property> </property>
<property name="maximum" > <property name="maximum">
<number>500</number> <number>500</number>
</property> </property>
<property name="value" > <property name="value">
<number>5</number> <number>5</number>
</property> </property>
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="tickPosition" > <property name="tickPosition">
<enum>QSlider::TicksAbove</enum> <enum>QSlider::TicksAbove</enum>
</property> </property>
<property name="tickInterval" > <property name="tickInterval">
<number>100</number> <number>100</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0" > <item row="2" column="0">
<widget class="QLabel" name="mediumLabel" > <widget class="QLabel" name="mediumLabel">
<property name="text" > <property name="text">
<string>Medium</string> <string>Medium</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2" > <item row="2" column="2">
<widget class="QSlider" name="mediumSlider" > <widget class="QSlider" name="mediumSlider">
<property name="minimum" > <property name="minimum">
<number>5</number> <number>5</number>
</property> </property>
<property name="maximum" > <property name="maximum">
<number>500</number> <number>500</number>
</property> </property>
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="tickPosition" > <property name="tickPosition">
<enum>QSlider::TicksAbove</enum> <enum>QSlider::TicksAbove</enum>
</property> </property>
<property name="tickInterval" > <property name="tickInterval">
<number>100</number> <number>100</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" > <item row="3" column="0">
<widget class="QLabel" name="strongLabel" > <widget class="QLabel" name="strongLabel">
<property name="text" > <property name="text">
<string>Strong</string> <string>Strong</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2" > <item row="3" column="2">
<widget class="QSlider" name="strongSlider" > <widget class="QSlider" name="strongSlider">
<property name="minimum" > <property name="minimum">
<number>5</number> <number>5</number>
</property> </property>
<property name="maximum" > <property name="maximum">
<number>500</number> <number>500</number>
</property> </property>
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="tickPosition" > <property name="tickPosition">
<enum>QSlider::TicksAbove</enum> <enum>QSlider::TicksAbove</enum>
</property> </property>
<property name="tickInterval" > <property name="tickInterval">
<number>100</number> <number>100</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="4" > <item row="1" column="4">
<widget class="UBCircleFrame" name="fineDisplayFrame" > <widget class="UBCircleFrame" name="fineDisplayFrame">
<property name="sizePolicy" > <property name="sizePolicy">
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" > <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>60</horstretch> <horstretch>60</horstretch>
<verstretch>60</verstretch> <verstretch>60</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize" > <property name="minimumSize">
<size> <size>
<width>60</width> <width>60</width>
<height>60</height> <height>60</height>
</size> </size>
</property> </property>
<property name="frameShape" > <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="4" > <item row="2" column="4">
<widget class="UBCircleFrame" name="mediumDisplayFrame" > <widget class="UBCircleFrame" name="mediumDisplayFrame">
<property name="sizePolicy" > <property name="sizePolicy">
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" > <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>60</horstretch> <horstretch>60</horstretch>
<verstretch>60</verstretch> <verstretch>60</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize" > <property name="minimumSize">
<size> <size>
<width>60</width> <width>60</width>
<height>60</height> <height>60</height>
</size> </size>
</property> </property>
<property name="frameShape" > <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="4" > <item row="3" column="4">
<widget class="UBCircleFrame" name="strongDisplayFrame" > <widget class="UBCircleFrame" name="strongDisplayFrame">
<property name="sizePolicy" > <property name="sizePolicy">
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" > <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>60</horstretch> <horstretch>60</horstretch>
<verstretch>60</verstretch> <verstretch>60</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize" > <property name="minimumSize">
<size> <size>
<width>60</width> <width>60</width>
<height>60</height> <height>60</height>
</size> </size>
</property> </property>
<property name="frameShape" > <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<property name="frameShadow" > <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" > <item row="1" column="0">
<widget class="QLabel" name="fineLabel" > <widget class="QLabel" name="fineLabel">
<property name="text" > <property name="text">
<string>Fine</string> <string>Fine</string>
</property> </property>
</widget> </widget>
@ -446,50 +408,85 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="5" column="0" colspan="3" > <item row="3" column="1">
<widget class="QFrame" name="pressureFrame" > <spacer name="cSpacer">
<property name="frameShape" > <property name="orientation">
<enum>QFrame::NoFrame</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="frameShadow" > <property name="sizeHint" stdset="0">
<enum>QFrame::Raised</enum> <size>
<width>20</width>
<height>40</height>
</size>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_4" > </spacer>
<property name="margin" > </item>
<number>0</number> <item row="1" column="0">
<spacer name="nwSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property> </property>
<item> <property name="sizeHint" stdset="0">
<spacer name="swSpacer" > <size>
<property name="orientation" > <width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2">
<spacer name="neSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>0</width>
<height>20</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="5" column="0" colspan="3">
<widget class="QFrame" name="pressureFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QCheckBox" name="pressureSensitiveCheckBox" > <widget class="QCheckBox" name="pressureSensitiveCheckBox">
<property name="sizePolicy" > <property name="sizePolicy">
<sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" > <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text" > <property name="text">
<string>Pen is Pressure Sensitive</string> <string>Pen is Pressure Sensitive</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="seSpacer" > <spacer name="seSpacer">
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>198</width> <width>198</width>
<height>20</height> <height>20</height>
@ -500,6 +497,30 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="7" column="0" colspan="2">
<layout class="QHBoxLayout" name="interpolationFrame">
<item>
<widget class="QCheckBox" name="interpolateStrokesCheckBox">
<property name="text">
<string>Smooth strokes (experimental)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

@ -165,6 +165,7 @@ void UBPreferencesController::wire()
connect(mPenProperties->mediumSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int))); connect(mPenProperties->mediumSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int)));
connect(mPenProperties->strongSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int))); connect(mPenProperties->strongSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int)));
connect(mPenProperties->pressureSensitiveCheckBox, SIGNAL(clicked(bool)), settings, SLOT(setPenPressureSensitive(bool))); connect(mPenProperties->pressureSensitiveCheckBox, SIGNAL(clicked(bool)), settings, SLOT(setPenPressureSensitive(bool)));
connect(mPenProperties->interpolateStrokesCheckBox, SIGNAL(clicked(bool)), settings->boardInterpolatePenStrokes, SLOT(setBool(bool)));
// marker // marker
QList<QColor> markerLightBackgroundColors = settings->boardMarkerLightBackgroundColors->colors(); QList<QColor> markerLightBackgroundColors = settings->boardMarkerLightBackgroundColors->colors();
@ -231,6 +232,7 @@ void UBPreferencesController::init()
mPenProperties->mediumSlider->setValue(settings->boardPenMediumWidth->get().toDouble() * sSliderRatio); mPenProperties->mediumSlider->setValue(settings->boardPenMediumWidth->get().toDouble() * sSliderRatio);
mPenProperties->strongSlider->setValue(settings->boardPenStrongWidth->get().toDouble() * sSliderRatio); mPenProperties->strongSlider->setValue(settings->boardPenStrongWidth->get().toDouble() * sSliderRatio);
mPenProperties->pressureSensitiveCheckBox->setChecked(settings->boardPenPressureSensitive->get().toBool()); mPenProperties->pressureSensitiveCheckBox->setChecked(settings->boardPenPressureSensitive->get().toBool());
mPenProperties->interpolateStrokesCheckBox->setChecked(settings->boardInterpolatePenStrokes->get().toBool());
// marker tab // marker tab
mMarkerProperties->fineSlider->setValue(settings->boardMarkerFineWidth->get().toDouble() * sSliderRatio); mMarkerProperties->fineSlider->setValue(settings->boardMarkerFineWidth->get().toDouble() * sSliderRatio);

@ -269,6 +269,8 @@ void UBSettings::init()
boardUseHighResTabletEvent = new UBSetting(this, "Board", "UseHighResTabletEvent", true); boardUseHighResTabletEvent = new UBSetting(this, "Board", "UseHighResTabletEvent", true);
boardInterpolatePenStrokes = new UBSetting(this, "Board", "InterpolatePenStrokes", true);
boardKeyboardPaletteKeyBtnSize = new UBSetting(this, "Board", "KeyboardPaletteKeyBtnSize", "16x16"); boardKeyboardPaletteKeyBtnSize = new UBSetting(this, "Board", "KeyboardPaletteKeyBtnSize", "16x16");
ValidateKeyboardPaletteKeyBtnSize(); ValidateKeyboardPaletteKeyBtnSize();

@ -273,6 +273,8 @@ class UBSettings : public QObject
UBSetting* boardUseHighResTabletEvent; UBSetting* boardUseHighResTabletEvent;
UBSetting* boardInterpolatePenStrokes;
UBSetting* boardKeyboardPaletteKeyBtnSize; UBSetting* boardKeyboardPaletteKeyBtnSize;
UBSetting* appStartMode; UBSetting* appStartMode;

@ -25,6 +25,7 @@
*/ */
#include <unistd.h>
#include "UBGraphicsScene.h" #include "UBGraphicsScene.h"
@ -37,6 +38,7 @@
#include "frameworks/UBGeometryUtils.h" #include "frameworks/UBGeometryUtils.h"
#include "frameworks/UBPlatformUtils.h" #include "frameworks/UBPlatformUtils.h"
#include "frameworks/UBInterpolator.h"
#include "core/UBApplication.h" #include "core/UBApplication.h"
#include "core/UBSettings.h" #include "core/UBSettings.h"
@ -335,6 +337,7 @@ UBGraphicsScene::UBGraphicsScene(UBDocumentProxy* parent, bool enableUndoRedoSta
, mZLayerController(new UBZLayerController(this)) , mZLayerController(new UBZLayerController(this))
, mpLastPolygon(NULL) , mpLastPolygon(NULL)
, mCurrentPolygon(0) , mCurrentPolygon(0)
, mTempPolygon(NULL)
, mSelectionFrame(0) , mSelectionFrame(0)
{ {
UBCoreGraphicsScene::setObjectName("BoardScene"); UBCoreGraphicsScene::setObjectName("BoardScene");
@ -434,6 +437,8 @@ bool UBGraphicsScene::inputDevicePress(const QPointF& scenePos, const qreal& pre
else { else {
moveTo(scenePos); moveTo(scenePos);
drawLineTo(scenePos, width, UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line); drawLineTo(scenePos, width, UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line);
mCurrentStroke->addPoint(scenePos);
} }
accepted = true; accepted = true;
} }
@ -537,11 +542,47 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres
position = newPosition; position = newPosition;
} }
if (!mCurrentStroke)
mCurrentStroke = new UBGraphicsStroke();
if(dc->mActiveRuler){ if(dc->mActiveRuler){
dc->mActiveRuler->DrawLine(position, width); dc->mActiveRuler->DrawLine(position, width);
} }
else{ else{
drawLineTo(position, width, UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line); UBInterpolator::InterpolationMethod interpolator = UBInterpolator::NoInterpolation;
/*
if (currentTool == UBStylusTool::Marker) {
// The marker is already super slow due to the transparency, we can't also do interpolation
interpolator = UBInterpolator::NoInterpolation;
}
*/
if (UBSettings::settings()->boardInterpolatePenStrokes->get().toBool()) {
interpolator = UBInterpolator::Bezier;
}
QList<QPointF> newPoints = mCurrentStroke->addPoint(scenePos, interpolator);
if (newPoints.length() > 1) {
drawCurve(newPoints, mPreviousWidth, width);
}
if (interpolator == UBInterpolator::Bezier) {
// Bezier curves aren't drawn all the way to the scenePos (they stop halfway between the previous and
// current scenePos), so we add a line from the last drawn position in the stroke and the
// scenePos, to make the drawing feel more responsive. This line is then deleted if a new segment is
// added to the stroke. (Or it is added to the stroke when we stop drawing)
if (mTempPolygon) {
removeItem(mTempPolygon);
mTempPolygon = NULL;
}
QPointF lastDrawnPoint = newPoints.last();
mTempPolygon = lineToPolygonItem(QLineF(lastDrawnPoint, scenePos), mPreviousWidth, width);
addItem(mTempPolygon);
}
} }
} }
else if (currentTool == UBStylusTool::Eraser) else if (currentTool == UBStylusTool::Eraser)
@ -610,6 +651,13 @@ bool UBGraphicsScene::inputDeviceRelease()
mDrawWithCompass = false; mDrawWithCompass = false;
} }
else if (mCurrentStroke){ else if (mCurrentStroke){
if (mTempPolygon) {
UBGraphicsPolygonItem * poly = dynamic_cast<UBGraphicsPolygonItem*>(mTempPolygon->deepCopy());
removeItem(mTempPolygon);
mTempPolygon = NULL;
addPolygonItemToCurrentStroke(poly);
}
UBGraphicsStrokesGroup* pStrokes = new UBGraphicsStrokesGroup(); UBGraphicsStrokesGroup* pStrokes = new UBGraphicsStrokesGroup();
// Remove the strokes that were just drawn here and replace them by a stroke item // Remove the strokes that were just drawn here and replace them by a stroke item
@ -775,16 +823,51 @@ void UBGraphicsScene::moveTo(const QPointF &pPoint)
mArcPolygonItem = 0; mArcPolygonItem = 0;
mDrawWithCompass = false; mDrawWithCompass = false;
} }
void UBGraphicsScene::drawLineTo(const QPointF &pEndPoint, const qreal &pWidth, bool bLineStyle) void UBGraphicsScene::drawLineTo(const QPointF &pEndPoint, const qreal &pWidth, bool bLineStyle)
{
drawLineTo(pEndPoint, pWidth, pWidth, bLineStyle);
}
void UBGraphicsScene::drawLineTo(const QPointF &pEndPoint, const qreal &startWidth, const qreal &endWidth, bool bLineStyle)
{ {
if (mPreviousWidth == -1.0) if (mPreviousWidth == -1.0)
mPreviousWidth = pWidth; mPreviousWidth = startWidth;
// UBGraphicsPolygonItem *polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), pWidth); qreal initialWidth = startWidth;
if (initialWidth == endWidth)
initialWidth = mPreviousWidth;
if (bLineStyle) {
QSetIterator<QGraphicsItem*> itItems(mAddedItems);
while (itItems.hasNext()) {
QGraphicsItem* item = itItems.next();
removeItem(item);
}
mAddedItems.clear();
}
UBGraphicsPolygonItem *polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), mPreviousWidth,pWidth); UBGraphicsPolygonItem *polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), initialWidth, endWidth);
addPolygonItemToCurrentStroke(polygonItem);
if (!bLineStyle) {
mPreviousPoint = pEndPoint;
mPreviousWidth = endWidth;
}
}
void UBGraphicsScene::drawCurve(const QList<QPointF>& points, qreal startWidth, qreal endWidth)
{
UBGraphicsPolygonItem* polygonItem = curveToPolygonItem(points, startWidth, endWidth);
addPolygonItemToCurrentStroke(polygonItem);
mPreviousWidth = endWidth;
mPreviousPoint = points.last();
}
void UBGraphicsScene::addPolygonItemToCurrentStroke(UBGraphicsPolygonItem* polygonItem)
{
if (!polygonItem->brush().isOpaque()) if (!polygonItem->brush().isOpaque())
{ {
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
@ -797,19 +880,6 @@ void UBGraphicsScene::drawLineTo(const QPointF &pEndPoint, const qreal &pWidth,
} }
} }
if (bLineStyle)
{
QSetIterator<QGraphicsItem*> itItems(mAddedItems);
while (itItems.hasNext())
{
QGraphicsItem* item = itItems.next();
removeItem(item);
}
mAddedItems.clear();
}
mpLastPolygon = polygonItem; mpLastPolygon = polygonItem;
mAddedItems.insert(polygonItem); mAddedItems.insert(polygonItem);
@ -822,12 +892,6 @@ void UBGraphicsScene::drawLineTo(const QPointF &pEndPoint, const qreal &pWidth,
mPreviousPolygonItems.append(polygonItem); mPreviousPolygonItems.append(polygonItem);
if (!bLineStyle)
{
mPreviousPoint = pEndPoint;
mPreviousWidth = pWidth;
}
} }
void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth) void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth)
@ -1087,6 +1151,14 @@ UBGraphicsPolygonItem* UBGraphicsScene::arcToPolygonItem(const QLineF& pStartRad
return polygonToPolygonItem(polygon); return polygonToPolygonItem(polygon);
} }
UBGraphicsPolygonItem* UBGraphicsScene::curveToPolygonItem(const QList<QPointF>& points, qreal startWidth, qreal endWidth)
{
QPolygonF polygon = UBGeometryUtils::curveToPolygon(points, startWidth, endWidth);
return polygonToPolygonItem(polygon);
}
void UBGraphicsScene::clearSelectionFrame() void UBGraphicsScene::clearSelectionFrame()
{ {
if (mSelectionFrame) { if (mSelectionFrame) {

@ -193,8 +193,10 @@ class UBGraphicsScene: public UBCoreGraphicsScene, public UBItem
void moveTo(const QPointF& pPoint); void moveTo(const QPointF& pPoint);
void drawLineTo(const QPointF& pEndPoint, const qreal& pWidth, bool bLineStyle); void drawLineTo(const QPointF& pEndPoint, const qreal& pWidth, bool bLineStyle);
void drawLineTo(const QPointF& pEndPoint, const qreal& pStartWidth, const qreal& endWidth, bool bLineStyle);
void eraseLineTo(const QPointF& pEndPoint, const qreal& pWidth); void eraseLineTo(const QPointF& pEndPoint, const qreal& pWidth);
void drawArcTo(const QPointF& pCenterPoint, qreal pSpanAngle); void drawArcTo(const QPointF& pCenterPoint, qreal pSpanAngle);
void drawCurve(const QList<QPointF>& points, qreal startWidth, qreal endWidth);
bool isEmpty() const; bool isEmpty() const;
@ -366,6 +368,8 @@ public slots:
UBGraphicsPolygonItem* lineToPolygonItem(const QLineF &pLine, const qreal &pStartWidth, const qreal &pEndWidth); UBGraphicsPolygonItem* lineToPolygonItem(const QLineF &pLine, const qreal &pStartWidth, const qreal &pEndWidth);
UBGraphicsPolygonItem* arcToPolygonItem(const QLineF& pStartRadius, qreal pSpanAngle, qreal pWidth); UBGraphicsPolygonItem* arcToPolygonItem(const QLineF& pStartRadius, qreal pSpanAngle, qreal pWidth);
UBGraphicsPolygonItem* curveToPolygonItem(const QList<QPointF>& points, qreal startWidth, qreal endWidth);
void addPolygonItemToCurrentStroke(UBGraphicsPolygonItem* polygonItem);
void initPolygonItem(UBGraphicsPolygonItem*); void initPolygonItem(UBGraphicsPolygonItem*);
@ -450,6 +454,7 @@ public slots:
UBZLayerController *mZLayerController; UBZLayerController *mZLayerController;
UBGraphicsPolygonItem* mpLastPolygon; UBGraphicsPolygonItem* mpLastPolygon;
UBGraphicsPolygonItem* mTempPolygon;
bool mDrawWithCompass; bool mDrawWithCompass;
UBGraphicsPolygonItem *mCurrentPolygon; UBGraphicsPolygonItem *mCurrentPolygon;

@ -31,11 +31,14 @@
#include "UBGraphicsPolygonItem.h" #include "UBGraphicsPolygonItem.h"
#include "board/UBBoardController.h"
#include "core/UBApplication.h"
#include "core/memcheck.h" #include "core/memcheck.h"
UBGraphicsStroke::UBGraphicsStroke() UBGraphicsStroke::UBGraphicsStroke()
{ {
// NOOP mAntiScaleRatio = 1./(UBApplication::boardController->systemScaleFactor() * UBApplication::boardController->currentZoom());
} }
@ -63,6 +66,76 @@ QList<UBGraphicsPolygonItem*> UBGraphicsStroke::polygons() const
return mPolygons; return mPolygons;
} }
/**
* @brief Add a point to the curve, interpolating extra points if required
* @return The points (or point, if none were interpolated) that were added
*/
QList<QPointF> UBGraphicsStroke::addPoint(const QPointF& point, UBInterpolator::InterpolationMethod interpolationMethod)
{
int n = mReceivedPoints.size();
if (n == 0) {
mReceivedPoints << point;
mDrawnPoints << point;
return QList<QPointF>();
}
if (interpolationMethod == UBInterpolator::NoInterpolation) {
QPointF lastPoint = mReceivedPoints.last();
mReceivedPoints << point;
mDrawnPoints << point;
return QList<QPointF>() << lastPoint << point;
}
else if (interpolationMethod == UBInterpolator::Bezier) {
// This is a bit special, as the curve we are interpolating is not between two drawn points;
// it is between the midway points of the second-to-last and last point, and last and current point.
// Don't draw segments smaller than a certain length. This can help with performance
// (less polygons in a stroke) but mostly with keeping the curve smooth.
qreal MIN_DISTANCE = 5*mAntiScaleRatio;
qreal distance = QLineF(mReceivedPoints.last(), point).length();
if (distance < MIN_DISTANCE) {
return QList<QPointF>() << mDrawnPoints.last();
}
// The first segment is just a straight line to the first midway point
if (n == 1) {
QPointF lastPoint = mReceivedPoints[0];
mReceivedPoints << point;
mDrawnPoints << QPointF((lastPoint + point)/2.0);
return QList<QPointF>() << lastPoint << ((lastPoint + point)/2.0);
}
QPointF p0 = mReceivedPoints[mReceivedPoints.size() - 2];
QPointF p1 = mReceivedPoints[mReceivedPoints.size() - 1];
QPointF p2 = point;
UBQuadraticBezier bz;
QPointF startPoint = (p1+p0)/2.0;
QPointF endPoint = (p2+p1)/2.0;
bz.setPoints(startPoint, p1, endPoint);
QList<QPointF> newPoints = bz.getPoints(10);
// avoid adding duplicates
if (newPoints.first() == mDrawnPoints.last())
mDrawnPoints.removeLast();
foreach(QPointF p, newPoints) {
mDrawnPoints << p;
}
mReceivedPoints << point;
return newPoints;
}
return QList<QPointF>();
}
bool UBGraphicsStroke::hasPressure() bool UBGraphicsStroke::hasPressure()
{ {
@ -106,4 +179,3 @@ void UBGraphicsStroke::clear()
mPolygons.clear(); mPolygons.clear();
} }
} }

@ -33,6 +33,8 @@
#include <QtGui> #include <QtGui>
#include "core/UB.h" #include "core/UB.h"
#include "frameworks/UBInterpolator.h"
class UBGraphicsPolygonItem; class UBGraphicsPolygonItem;
@ -57,6 +59,10 @@ class UBGraphicsStroke
void clear(); void clear();
QList<QPointF> addPoint(const QPointF& point, UBInterpolator::InterpolationMethod interpolationMethod = UBInterpolator::NoInterpolation);
const QList<QPointF>& points() { return mDrawnPoints; }
protected: protected:
void addPolygon(UBGraphicsPolygonItem* pol); void addPolygon(UBGraphicsPolygonItem* pol);
@ -64,6 +70,13 @@ class UBGraphicsStroke
QList<UBGraphicsPolygonItem*> mPolygons; QList<UBGraphicsPolygonItem*> mPolygons;
/// Points that were drawn by the user (i.e, actually received through input device)
QList<QPointF> mReceivedPoints;
/// All the points (including interpolated) that are used to draw the stroke
QList<QPointF> mDrawnPoints;
qreal mAntiScaleRatio;
}; };
#endif /* UBGRAPHICSSTROKE_H_ */ #endif /* UBGRAPHICSSTROKE_H_ */

@ -244,6 +244,111 @@ QPolygonF UBGeometryUtils::arcToPolygon(const QLineF& startRadius, qreal spanAng
return painterPath.toFillPolygon(); return painterPath.toFillPolygon();
} }
/**
* @brief Build and return a polygon from a list of points (at least 2), and start and end widths.
*
* The resulting polygon will pass by all points in the curve; its thickness is calculated at each point
* of the curve (linearly interpolated between start and end widths) and the segments are joined by
* (approximately) curved joints.
*
* Like with lineToPolygon, the ends are semi-circular.
*/
QPolygonF UBGeometryUtils::curveToPolygon(const QList<QPointF>& points, qreal startWidth, qreal endWidth)
{
typedef QPair<QPointF, QPointF> pointPair;
int n_points = points.size();
if (n_points < 2)
return QPolygonF();
if (n_points == 2)
return lineToPolygon(points[0], points[1], startWidth, endWidth);
/* The vertices (x's) are calculated based on the stroke's width and angle, and the position of the
supplied points (o's):
x----------x--------x
o o o
x----------x -------x
The vertices above and below each 'o' point are temporarily stored together,
as a pair of points.
*/
QList<pointPair> newPoints;
QLineF firstSegment = QLineF(points[0], points[1]);
QLineF normal = firstSegment.normalVector();
normal.setLength(startWidth/2.0);
newPoints << pointPair(normal.p2(), points[0] - QPointF(normal.dx(), normal.dy()));
/*
Calculating the vertices (d1 and d2, below) is a little less trivial for the
next points: their positions depend on the angle between one segment and the next.
d1
------------x
\
.a b . \
\
--------x \
d2 \ \
\ .c \
Here, points a, b and c are supplied in the `points` list.
N.B: The drawing isn't quite accurate; we don't do a miter joint but a kind
of rounded-off joint (the distance between b and d1 is half the width of the stroke)
*/
for (int i(1); i < n_points-1; ++i) {
qreal width = startWidth + (qreal(i)/qreal(n_points-1)) * (endWidth - startWidth);
QLineF normal = (QLineF(points[i-1], points[i+1])).normalVector();
normal.setLength(width/2.0);
QPointF d1 = points[i] + QPointF(normal.dx(), normal.dy());
QPointF d2 = points[i] - QPointF(normal.dx(), normal.dy());
newPoints << pointPair(d1, d2);
}
// The last point is similar to the first
QLineF lastSegment = QLineF(points[n_points-2], points[n_points-1]);
normal = lastSegment.normalVector();
normal.setLength(endWidth/2.0);
QPointF d1 = points.last() + QPointF(normal.dx(), normal.dy());
QPointF d2 = points.last() - QPointF(normal.dx(), normal.dy());
newPoints << pointPair(d1, d2);
QPainterPath path;
path.moveTo(newPoints[0].first);
for (int i(1); i < n_points; ++i) {
path.lineTo(newPoints[i].first);
}
path.arcTo(points.last().x() - endWidth/2.0, points.last().y() - endWidth/2.0, endWidth, endWidth, (90.0 + lastSegment.angle()), -180.0);
//path.lineTo(newPoints.last().second);
for (int i(n_points-1); i >= 0; --i) {
path.lineTo(newPoints[i].second);
}
path.arcTo(points[0].x() - startWidth/2.0, points[0].y() - startWidth/2.0, startWidth, startWidth, (firstSegment.angle() - 90.0), -180.0);
//path.lineTo(newPoints[0].second);
path.closeSubpath();
return path.toFillPolygon();
}
QPointF UBGeometryUtils::pointConstrainedInRect(QPointF point, QRectF rect) QPointF UBGeometryUtils::pointConstrainedInRect(QPointF point, QRectF rect)
{ {
return QPointF(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y()))); return QPointF(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y())));

@ -47,6 +47,7 @@ class UBGeometryUtils
static QPolygonF lineToPolygon(const QPointF& pStart, const QPointF& pEnd, static QPolygonF lineToPolygon(const QPointF& pStart, const QPointF& pEnd,
const qreal& pStartWidth, const qreal& pEndWidth); const qreal& pStartWidth, const qreal& pEndWidth);
static QPolygonF curveToPolygon(const QList<QPointF>& points, qreal startWidth, qreal endWidth);
static QPointF pointConstrainedInRect(QPointF point, QRectF rect); static QPointF pointConstrainedInRect(QPointF point, QRectF rect);
static QPoint pointConstrainedInRect(QPoint point, QRect rect); static QPoint pointConstrainedInRect(QPoint point, QRect rect);

@ -0,0 +1,53 @@
#include "UBInterpolator.h"
UBInterpolator::UBInterpolator()
{
}
UBInterpolator::~UBInterpolator()
{
}
UBQuadraticBezier::UBQuadraticBezier()
{
mPath = 0;
}
UBQuadraticBezier::~UBQuadraticBezier()
{
if (mPath)
delete mPath;
}
void UBQuadraticBezier::setPoints(QList<QPointF> points)
{
setPoints(points[0], points[1], points[2]);
}
void UBQuadraticBezier::setPoints(QPointF start, QPointF control, QPointF end)
{
mPath = new QPainterPath(start);
mPath->quadTo(control, end);
}
/**
* @brief Return n points along the curve, including start and end points (thus n should be larger than or equal to 2).
*
* The higher n, the more accurate the result
*/
QList<QPointF> UBQuadraticBezier::getPoints(int n)
{
QList<QPointF> points;
if (n <= 1)
return points;
for (int i(0); i <= n; ++i) {
qreal percent = qreal(i)/qreal(n);
points << mPath->pointAtPercent(percent);
}
return points;
}

@ -0,0 +1,45 @@
#ifndef UBINTERPOLATOR_H
#define UBINTERPOLATOR_H
#include <QtGui>
class UBInterpolator
{
/* Abstract class representing an interpolator */
public:
enum InterpolationMethod {
NoInterpolation,
//SimpleSpline,
//CatmullRom,
Bezier
};
UBInterpolator();
virtual ~UBInterpolator();
virtual void setPoints(QList<QPointF> points) = 0;
//virtual double y(double x) {}
};
class UBQuadraticBezier : public UBInterpolator
{
public:
UBQuadraticBezier();
virtual ~UBQuadraticBezier();
virtual void setPoints(QList<QPointF> points);
void setPoints(QPointF start, QPointF control, QPointF end);
//virtual double y(double x);
QList<QPointF> getPoints(int n);
private:
QPainterPath* mPath;
};
#endif // UBINTERPOLATOR_H

@ -6,7 +6,8 @@ HEADERS += src/frameworks/UBGeometryUtils.h \
src/frameworks/UBVersion.h \ src/frameworks/UBVersion.h \
src/frameworks/UBCoreGraphicsScene.h \ src/frameworks/UBCoreGraphicsScene.h \
src/frameworks/UBCryptoUtils.h \ src/frameworks/UBCryptoUtils.h \
src/frameworks/UBBase32.h src/frameworks/UBBase32.h \
$$PWD/UBInterpolator.h
SOURCES += src/frameworks/UBGeometryUtils.cpp \ SOURCES += src/frameworks/UBGeometryUtils.cpp \
src/frameworks/UBPlatformUtils.cpp \ src/frameworks/UBPlatformUtils.cpp \
@ -15,7 +16,8 @@ SOURCES += src/frameworks/UBGeometryUtils.cpp \
src/frameworks/UBVersion.cpp \ src/frameworks/UBVersion.cpp \
src/frameworks/UBCoreGraphicsScene.cpp \ src/frameworks/UBCoreGraphicsScene.cpp \
src/frameworks/UBCryptoUtils.cpp \ src/frameworks/UBCryptoUtils.cpp \
src/frameworks/UBBase32.cpp src/frameworks/UBBase32.cpp \
$$PWD/UBInterpolator.cpp
win32 { win32 {

Loading…
Cancel
Save