> AFAICS, you have not defined a default length, but a default unit. This might
> be confused with the already used defaultUnit(), and it doesn't look like a
> clean solution.
>
> The by far best method, I think, would be to setup a HSpace class similar to
> the VSpace class. This class could inherit Length and DEFAULT. I.e.,
>
>         enum HSpaceKind {
>                 DEFAULT,
>                 LENGTH ///< user-defined length
>         };

This is now the case in the attached patch.

>> +               // when separation by indentation
>> +               // only output something when a indetn width is given
>> +               if (getIndentation().value() > 0) {
>
> Why value() > 0? Am I not allowed to set the indendation to "0em"?

This is now fixed.

>> +       // remove the %-items from the unit choices
>> +       textLayoutModule->indentLengthCO->noPercents();
>
> \setlength{\parindent}{.05\columnwidth} works for me and strikes me not too
> absurd.

Percent lengths are now allowed. However, percent lengths are also allowed for skip separation. This is now http://www.lyx.org/trac/ticket/6091
I failed to fix this bug although is sees to be easy.

>> +       // clear values, otherwise one would get for a new document the
>> +       // same settings as default as for a currently opened document
>
> It strikes me wrong to do this in the frontend.
> Probably in Buffer::readHeader(Lexer & lex)?

It had no effect and I therefore removed it now. Doing this in 
Buffer::readHeader has also no effect.

My patch is ready to go in I think. The only thing that is missing is visual feedback for the indentation width. As LyX source code is not documented, it was impossible for me to find out how and where the visual feedback for the paragraph skip separation is set. When you point me to this code, I'll also implement the visual feedback for indentation.

regards Uwe
Index: BufferParams.cpp
===================================================================
--- BufferParams.cpp	(revision 30639)
+++ BufferParams.cpp	(working copy)
@@ -289,6 +289,7 @@
 	/** This is the amount of space used for paragraph_separation "skip",
 	 * and for detached paragraphs in "indented" documents.
 	 */
+	Length indentation;
 	VSpace defskip;
 	PDFOptions pdfoptions;
 	LayoutFileIndex baseClass_;
@@ -468,6 +469,18 @@
 }
 
 
+Length const & BufferParams::getIndentation() const
+{
+	return pimpl_->indentation;
+}
+
+
+void BufferParams::setIndentation(Length const & indent)
+{
+	pimpl_->indentation = indent;
+}
+
+
 VSpace const & BufferParams::getDefSkip() const
 {
 	return pimpl_->defskip;
@@ -566,6 +579,13 @@
 		string parsep;
 		lex >> parsep;
 		paragraph_separation = parseptranslator().find(parsep);
+	} else if (token == "\\paragraph_indentation") {
+		lex.next();
+		string indentation = lex.getString();
+		if (indentation == "default")
+			pimpl_->indentation = Length(Length::DEFAULT);
+		else
+			pimpl_->indentation = Length(indentation);
 	} else if (token == "\\defskip") {
 		lex.next();
 		string defskip = lex.getString();
@@ -903,9 +923,12 @@
 	os << "\\secnumdepth " << secnumdepth
 	   << "\n\\tocdepth " << tocdepth
 	   << "\n\\paragraph_separation "
-	   << string_paragraph_separation[paragraph_separation]
-	   << "\n\\defskip " << getDefSkip().asLyXCommand()
-	   << "\n\\quotes_language "
+	   << string_paragraph_separation[paragraph_separation];
+	if (!paragraph_separation)
+		os << "\n\\paragraph_indentation " << getIndentation().asString();
+	else
+		os << "\n\\defskip " << getDefSkip().asLyXCommand();
+	os << "\n\\quotes_language "
 	   << string_quotes_language[quotes_language]
 	   << "\n\\papercolumns " << columns
 	   << "\n\\papersides " << sides
@@ -1370,6 +1393,7 @@
 	}
 
 	if (paragraph_separation) {
+		// when skip separation
 		switch (getDefSkip().kind()) {
 		case VSpace::SMALLSKIP:
 			os << "\\setlength{\\parskip}{\\smallskipamount}\n";
@@ -1390,9 +1414,19 @@
 			break;
 		}
 		texrow.newline();
-
 		os << "\\setlength{\\parindent}{0pt}\n";
 		texrow.newline();
+	} else {
+		// when separation by indentation
+		// only output something when a width is given
+		// "0" is the case for a new document
+		if (getIndentation().asString() != "default"
+			&& getIndentation().asString() != "0") {
+			os << "\\setlength{\\parindent}{"
+			   << from_utf8(getIndentation().asLatexString())
+			   << "}\n";
+			texrow.newline();
+		}
 	}
 
 	// Now insert the LyX specific LaTeX commands...
Index: BufferParams.h
===================================================================
--- BufferParams.h	(revision 30639)
+++ BufferParams.h	(working copy)
@@ -41,6 +41,7 @@
 class LatexFeatures;
 class LayoutFile;
 class LayoutFileIndex;
+class Length;
 class Lexer;
 class PDFOptions;
 class Spacing;
@@ -90,6 +91,10 @@
 	bool hasClassDefaults() const;
 
 	///
+	Length const & getIndentation() const;
+	///
+	void setIndentation(Length const & indent);
+	///
 	VSpace const & getDefSkip() const;
 	///
 	void setDefSkip(VSpace const & vs);
Index: frontends/qt4/GuiDocument.cpp
===================================================================
--- frontends/qt4/GuiDocument.cpp	(revision 30639)
+++ frontends/qt4/GuiDocument.cpp	(working copy)
@@ -553,20 +553,38 @@
 		this, SLOT(setLSpacing(int)));
 	connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
 		this, SLOT(change_adaptor()));
+
+	connect(textLayoutModule->indentRB, SIGNAL(clicked()),
+		this, SLOT(change_adaptor()));
+	connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
+		textLayoutModule->indentCO, SLOT(setEnabled(bool)));
+	connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
+		this, SLOT(change_adaptor()));
+	connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
+		this, SLOT(setIndent(int)));
+	connect(textLayoutModule->indentLE, SIGNAL(textChanged(const QString &)),
+		this, SLOT(change_adaptor()));
+	connect(textLayoutModule->indentLengthCO, SIGNAL(activated(int)),
+		this, SLOT(change_adaptor()));
+
 	connect(textLayoutModule->skipRB, SIGNAL(clicked()),
 		this, SLOT(change_adaptor()));
-	connect(textLayoutModule->indentRB, SIGNAL(clicked()),
+	connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
+		textLayoutModule->skipCO, SLOT(setEnabled(bool)));
+	connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
 		this, SLOT(change_adaptor()));
 	connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
-		this, SLOT(change_adaptor()));
+		this, SLOT(setSkip(int)));
 	connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
 		this, SLOT(change_adaptor()));
 	connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
 		this, SLOT(change_adaptor()));
-	connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
-		this, SLOT(setSkip(int)));
+
+	connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
+		this, SLOT(enableIndent(bool)));
 	connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
 		this, SLOT(enableSkip(bool)));
+
 	connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
 		this, SLOT(change_adaptor()));
 	connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
@@ -583,9 +601,13 @@
 		qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
 	textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
 		textLayoutModule->lspacingLE));
+	textLayoutModule->indentLE->setValidator(unsignedLengthValidator(
+		textLayoutModule->indentLE));
 	textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
 		textLayoutModule->skipLE));
 
+	textLayoutModule->indentCO->addItem(qt_("Default"));
+	textLayoutModule->indentCO->addItem(qt_("Length"));
 	textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
 	textLayoutModule->skipCO->addItem(qt_("MedSkip"));
 	textLayoutModule->skipCO->addItem(qt_("BigSkip"));
@@ -600,8 +622,8 @@
 		Spacing::Double, qt_("Double"));
 	textLayoutModule->lspacingCO->insertItem(
 		Spacing::Other, qt_("Custom"));
-
 	// initialize the length validator
+	bc().addCheckedLineEdit(textLayoutModule->indentLE);
 	bc().addCheckedLineEdit(textLayoutModule->skipLE);
 
 	// output
@@ -1115,19 +1137,39 @@
 }
 
 
+void GuiDocument::setIndent(int item)
+{
+	bool const enable = (item == 1);
+	textLayoutModule->indentLE->setEnabled(enable);
+	textLayoutModule->indentLengthCO->setEnabled(enable);
+	textLayoutModule->skipLE->setEnabled(false);
+	textLayoutModule->skipLengthCO->setEnabled(false);
+	isValid();
+}
+
+
+void GuiDocument::enableIndent(bool indent)
+{
+	textLayoutModule->skipLE->setEnabled(!indent);
+	textLayoutModule->skipLengthCO->setEnabled(!indent);
+	if (indent)
+		setIndent(textLayoutModule->indentCO->currentIndex());
+}
+
+
 void GuiDocument::setSkip(int item)
 {
 	bool const enable = (item == 3);
 	textLayoutModule->skipLE->setEnabled(enable);
 	textLayoutModule->skipLengthCO->setEnabled(enable);
+	isValid();
 }
 
 
 void GuiDocument::enableSkip(bool skip)
 {
-	textLayoutModule->skipCO->setEnabled(skip);
-	textLayoutModule->skipLE->setEnabled(skip);
-	textLayoutModule->skipLengthCO->setEnabled(skip);
+	textLayoutModule->indentLE->setEnabled(!skip);
+	textLayoutModule->indentLengthCO->setEnabled(!skip);
 	if (skip)
 		setSkip(textLayoutModule->skipCO->currentIndex());
 }
@@ -1894,36 +1936,55 @@
 	bp_.listings_params =
 		InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
 
-	if (textLayoutModule->indentRB->isChecked())
+	if (textLayoutModule->indentRB->isChecked()) {
+		// if paragraphs are separated by an indentation
 		bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
-	else
+		switch (textLayoutModule->indentCO->currentIndex()) {
+		case 0:
+			bp_.setIndentation(Length(Length::DEFAULT));
+			break;
+		case 1:
+			{
+			Length indent = Length(
+				widgetsToLength(textLayoutModule->indentLE,
+				textLayoutModule->indentLengthCO)
+				);
+			bp_.setIndentation(indent);
+			break;
+			}
+		default:
+			// this should never happen
+			bp_.setIndentation(Length());
+			break;
+		}
+	} else {
+		// if paragraphs are separated by a skip
 		bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
-
-	switch (textLayoutModule->skipCO->currentIndex()) {
-	case 0:
-		bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
-		break;
-	case 1:
-		bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
-		break;
-	case 2:
-		bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
-		break;
-	case 3:
-	{
-		VSpace vs = VSpace(
-			widgetsToLength(textLayoutModule->skipLE,
+		switch (textLayoutModule->skipCO->currentIndex()) {
+		case 0:
+			bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
+			break;
+		case 1:
+			bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
+			break;
+		case 2:
+			bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
+			break;
+		case 3:
+			{
+			VSpace vs = VSpace(
+				widgetsToLength(textLayoutModule->skipLE,
 				textLayoutModule->skipLengthCO)
-			);
-		bp_.setDefSkip(vs);
-		break;
+				);
+			bp_.setDefSkip(vs);
+			break;
+			}
+		default:
+			// this should never happen
+			bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
+			break;
+		}
 	}
-	default:
-		// DocumentDefskipCB assures that this never happens
-		// so Assert then !!!  - jbl
-		bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
-		break;
-	}
 
 	bp_.options =
 		fromqstr(latexModule->optionsLE->text());
@@ -2210,37 +2271,50 @@
 	}
 	setLSpacing(nitem);
 
-	if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
+	if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
 		textLayoutModule->indentRB->setChecked(true);
-	else
+		string indentation = bp_.getIndentation().asString();
+		int indent = 0;
+		// "0" is the case for a new document
+		if (indentation == "default" || indentation == "0")
+			indent = 0;
+		else {
+			lengthToWidgets(textLayoutModule->indentLE,
+			textLayoutModule->indentLengthCO,
+			indentation, defaultUnit);
+			indent = 1;
+		}
+		textLayoutModule->indentCO->setCurrentIndex(indent);
+		setIndent(indent);
+	} else {
 		textLayoutModule->skipRB->setChecked(true);
-
-	int skip = 0;
-	switch (bp_.getDefSkip().kind()) {
-	case VSpace::SMALLSKIP:
-		skip = 0;
-		break;
-	case VSpace::MEDSKIP:
-		skip = 1;
-		break;
-	case VSpace::BIGSKIP:
-		skip = 2;
-		break;
-	case VSpace::LENGTH:
-	{
-		skip = 3;
-		string const length = bp_.getDefSkip().asLyXCommand();
-		lengthToWidgets(textLayoutModule->skipLE,
-			textLayoutModule->skipLengthCO,
-			length, defaultUnit);
-		break;
+		int skip = 0;
+		switch (bp_.getDefSkip().kind()) {
+		case VSpace::SMALLSKIP:
+			skip = 0;
+			break;
+		case VSpace::MEDSKIP:
+			skip = 1;
+			break;
+		case VSpace::BIGSKIP:
+			skip = 2;
+			break;
+		case VSpace::LENGTH:
+			{
+			skip = 3;
+			string const length = bp_.getDefSkip().asLyXCommand();
+			lengthToWidgets(textLayoutModule->skipLE,
+				textLayoutModule->skipLengthCO,
+				length, defaultUnit);
+			break;
+			}
+		default:
+			skip = 0;
+			break;
+		}
+		textLayoutModule->skipCO->setCurrentIndex(skip);
+		setSkip(skip);
 	}
-	default:
-		skip = 0;
-		break;
-	}
-	textLayoutModule->skipCO->setCurrentIndex(skip);
-	setSkip(skip);
 
 	textLayoutModule->twoColumnCB->setChecked(
 		bp_.columns == 2);
@@ -2539,7 +2613,11 @@
 {
 	return validateListingsParameters().isEmpty()
 		&& (textLayoutModule->skipCO->currentIndex() != 3
-			|| !textLayoutModule->skipLE->text().isEmpty());
+			|| !textLayoutModule->skipLE->text().isEmpty()
+			|| textLayoutModule->indentRB->isChecked())
+		&& (textLayoutModule->indentCO->currentIndex() != 1
+			|| !textLayoutModule->indentLE->text().isEmpty()
+			|| textLayoutModule->skipRB->isChecked());
 }
 
 
Index: frontends/qt4/GuiDocument.h
===================================================================
--- frontends/qt4/GuiDocument.h	(revision 30639)
+++ frontends/qt4/GuiDocument.h	(working copy)
@@ -93,6 +93,8 @@
 	void romanChanged(int);
 	void sansChanged(int);
 	void ttChanged(int);
+	void setIndent(int);
+	void enableIndent(bool);
 	void setSkip(int);
 	void enableSkip(bool);
 	void portraitChanged();
Index: frontends/qt4/ui/TextLayoutUi.ui
===================================================================
--- frontends/qt4/ui/TextLayoutUi.ui	(revision 30639)
+++ frontends/qt4/ui/TextLayoutUi.ui	(working copy)
@@ -5,8 +5,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>400</width>
-    <height>366</height>
+    <width>440</width>
+    <height>410</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -50,7 +50,111 @@
         </property>
        </widget>
       </item>
-      <item row="1" column="0">
+      <item row="0" column="1">
+       <widget class="QComboBox" name="indentCO">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>120</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>121</width>
+          <height>21</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>size of the vertical space</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2" colspan="2">
+       <spacer name="spacer_3">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeType">
+         <enum>QSizePolicy::Expanding</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>135</width>
+          <height>26</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLineEdit" name="indentLE">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>120</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>121</width>
+          <height>21</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>value</string>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="2">
+       <widget class="LengthCombo" name="indentLengthCO">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>121</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>21</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>unit</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="3">
+       <spacer name="spacer_4">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>48</width>
+          <height>26</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="2" column="0">
        <widget class="QRadioButton" name="skipRB">
         <property name="minimumSize">
          <size>
@@ -66,7 +170,7 @@
         </property>
        </widget>
       </item>
-      <item row="1" column="1">
+      <item row="2" column="1">
        <widget class="QComboBox" name="skipCO">
         <property name="enabled">
          <bool>false</bool>
@@ -88,7 +192,7 @@
         </property>
        </widget>
       </item>
-      <item row="1" column="2" colspan="2">
+      <item row="2" column="2" colspan="2">
        <spacer name="spacer_2">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
@@ -104,7 +208,7 @@
         </property>
        </spacer>
       </item>
-      <item row="2" column="1">
+      <item row="3" column="1">
        <widget class="QLineEdit" name="skipLE">
         <property name="enabled">
          <bool>false</bool>
@@ -132,20 +236,20 @@
         </property>
        </widget>
       </item>
-      <item row="2" column="2">
+      <item row="3" column="2">
        <widget class="LengthCombo" name="skipLengthCO">
         <property name="enabled">
          <bool>false</bool>
         </property>
         <property name="minimumSize">
          <size>
-          <width>69</width>
+          <width>121</width>
           <height>20</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
-          <width>70</width>
+          <width>16777215</width>
           <height>21</height>
          </size>
         </property>
@@ -154,18 +258,15 @@
         </property>
        </widget>
       </item>
-      <item row="2" column="3">
-       <spacer>
+      <item row="3" column="3">
+       <spacer name="spacer">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
-        <property name="sizeType">
-         <enum>QSizePolicy::Expanding</enum>
-        </property>
         <property name="sizeHint" stdset="0">
          <size>
-          <width>62</width>
-          <height>23</height>
+          <width>48</width>
+          <height>26</height>
          </size>
         </property>
        </spacer>
Index: Length.cpp
===================================================================
--- Length.cpp	(revision 30639)
+++ Length.cpp	(working copy)
@@ -35,17 +35,22 @@
 /////////////////////////////////////////////////////////////////////
 
 Length::Length()
-	: val_(0), unit_(Length::UNIT_NONE)
+	: kind_(LENGTH), val_(0), unit_(Length::UNIT_NONE)
 {}
 
 
+Length::Length(HSpaceKind h)
+	: kind_(h), val_(0), unit_(Length::UNIT_NONE)
+{}
+
+
 Length::Length(double v, Length::UNIT u)
-	: val_(v), unit_(u)
+	: kind_(LENGTH), val_(v), unit_(u)
 {}
 
 
 Length::Length(string const & data)
-	: val_(0), unit_(Length::PT)
+	: kind_(LENGTH), val_(0), unit_(Length::PT)
 {
 	Length tmp;
 
@@ -67,7 +72,10 @@
 string const Length::asString() const
 {
 	ostringstream os;
-	os << val_ << unit_name[unit_]; // setw?
+	if (kind_ == LENGTH)
+		os << val_ << unit_name[unit_]; // setw?
+	else
+		os << "default";
 	return os.str();
 }
 
@@ -75,7 +83,10 @@
 docstring const Length::asDocstring() const
 {
 	odocstringstream os;
-	os << val_ << unit_name[unit_]; // setw?
+	if (kind_ == LENGTH)
+		os << val_ << unit_name[unit_]; // setw?
+	else
+		os << from_ascii("default");
 	return os.str();
 }
 
@@ -83,28 +94,30 @@
 string const Length::asLatexString() const
 {
 	ostringstream os;
-	switch (unit_) {
-	case PTW:
-		os << val_ / 100.0 << "\\textwidth";
-		break;
-	case PCW:
-		os << val_ / 100.0 << "\\columnwidth";
-		break;
-	case PPW:
-		os << val_ / 100.0 << "\\paperwidth";
-		break;
-	case PLW:
-		os << val_ / 100.0 << "\\linewidth";
-		break;
-	case PPH:
-		os << val_ / 100.0 << "\\paperheight";
-		break;
-	case PTH:
-		os << val_ / 100.0 << "\\textheight";
-		break;
-	default:
-		os << val_ << unit_name[unit_];
-	  break;
+	if (kind_ == LENGTH) {
+		switch (unit_) {
+		case PTW:
+			os << val_ / 100.0 << "\\textwidth";
+			break;
+		case PCW:
+			os << val_ / 100.0 << "\\columnwidth";
+			break;
+		case PPW:
+			os << val_ / 100.0 << "\\paperwidth";
+			break;
+		case PLW:
+			os << val_ / 100.0 << "\\linewidth";
+			break;
+		case PPH:
+			os << val_ / 100.0 << "\\paperheight";
+			break;
+		case PTH:
+			os << val_ / 100.0 << "\\textheight";
+			break;
+		default:
+			os << val_ << unit_name[unit_];
+			break;
+		}
 	}
 	return os.str();
 }
@@ -113,40 +126,42 @@
 string const Length::asHTMLString() const
 {
 	ostringstream os;
-	switch (unit_) {
-	case PT:
- 	case BP:
-	case DD:
-		// close enough
-		os << val_ << "pt";
-		break;
- 	case MM:
-	case CM:
-	case PC:
-	case IN:
-	case EX:
-	case EM:
-		os << val_ << unit_name[unit_];
-		break;
-	case CC:
-		os << val_/12.0 << "pt";
-		break;
- 	case MU:
-		os << val_/18.0 << "em";
-		break;
-	case PTW:
-	case PPW:
-	case PLW:
-	case PCW:
-	case PTH:
-	case PPH:
-		// what it's a percentage of probably won't make sense for HTML,
-		// so we'll assume people have chosen these appropriately
-		os << val_ << '%';
-		break;
-	case SP:
-	case UNIT_NONE:
-		break;
+	if (kind_ == LENGTH) {
+		switch (unit_) {
+		case PT:
+		case BP:
+		case DD:
+			// close enough
+			os << val_ << "pt";
+			break;
+		case MM:
+		case CM:
+		case PC:
+		case IN:
+		case EX:
+		case EM:
+			os << val_ << unit_name[unit_];
+			break;
+		case CC:
+			os << val_/12.0 << "pt";
+			break;
+		case MU:
+			os << val_/18.0 << "em";
+			break;
+		case PTW:
+		case PPW:
+		case PLW:
+		case PCW:
+		case PTH:
+		case PPH:
+			// what it's a percentage of probably won't make sense for HTML,
+			// so we'll assume people have chosen these appropriately
+			os << val_ << '%';
+			break;
+		case SP:
+		case UNIT_NONE:
+			break;
+		}
 	}
 	return os.str();
 }
@@ -210,83 +225,85 @@
 
 	double result = 0.0;
 
-	switch (unit_) {
-	case Length::SP:
-		// Scaled point: sp = 1/65536 pt
-		result = zoom * dpi * val_
-			/ (72.27 * 65536); // 4736286.7
-		break;
-	case Length::PT:
-		// Point: 1 pt = 1/72.27 inch
-		result = zoom * dpi * val_
-			/ 72.27; // 72.27
-		break;
-	case Length::BP:
-		// Big point: 1 bp = 1/72 inch
-		result = zoom * dpi * val_
-			/ 72; // 72
-		break;
-	case Length::DD:
-		// Didot: 1157dd = 1238 pt?
-		result = zoom * dpi * val_
-			/ (72.27 / (0.376 * 2.845)); // 67.559735
-		break;
-	case Length::MM:
-		// Millimeter: 1 mm = 1/25.4 inch
-		result = zoom * dpi * val_
-			/ 25.4; // 25.4
-		break;
-	case Length::PC:
-		// Pica: 1 pc = 12 pt
-		result = zoom * dpi * val_
-			/ (72.27 / 12); // 6.0225
-		break;
-	case Length::CC:
-		// Cicero: 1 cc = 12 dd
-		result = zoom * dpi * val_
-			/ (72.27 / (12 * 0.376 * 2.845)); // 5.6299779
-		break;
-	case Length::CM:
-		// Centimeter: 1 cm = 1/2.54 inch
-		result = zoom * dpi * val_
-			/ 2.54; // 2.54
-		break;
-	case Length::IN:
-		// Inch
-		result = zoom * dpi * val_;
-		break;
-	case Length::EX:
-		// Ex: The height of an "x"
-		// 0.4305 is the ration between 1ex and 1em in cmr10
-		result = val_ * em_width * 0.4305;
-		break;
-	case Length::EM:
-		// Em: The width of an "m"
-		result = val_ * em_width;
-		break;
-	case Length::MU:
-		// math unit = 1/18em
-		result = val_ * em_width / 18;
-		break;
-	case Length::PCW: // Always % of workarea
-	case Length::PTW:
-	case Length::PLW:
-		result = val_ * text_width / 100;
-		break;
-	case Length::PPW:
-		// paperwidth/textwidth is 1.7 for A4 paper with default margins
-		result = val_ * text_width * 1.7 / 100;
-		break;
-	case Length::PTH:
-		result = val_ * text_width * 1.787 / 100;
-		break;
-	case Length::PPH:
-		result = val_ * text_width * 2.2 / 100;
-		break;
-	case Length::UNIT_NONE:
-		result = 0;  // this cannot happen
-		break;
-	}
+	if (kind_ == LENGTH) {
+		switch (unit_) {
+		case Length::SP:
+			// Scaled point: sp = 1/65536 pt
+			result = zoom * dpi * val_
+				/ (72.27 * 65536); // 4736286.7
+			break;
+		case Length::PT:
+			// Point: 1 pt = 1/72.27 inch
+			result = zoom * dpi * val_
+				/ 72.27; // 72.27
+			break;
+		case Length::BP:
+			// Big point: 1 bp = 1/72 inch
+			result = zoom * dpi * val_
+				/ 72; // 72
+			break;
+		case Length::DD:
+			// Didot: 1157dd = 1238 pt?
+			result = zoom * dpi * val_
+				/ (72.27 / (0.376 * 2.845)); // 67.559735
+			break;
+		case Length::MM:
+			// Millimeter: 1 mm = 1/25.4 inch
+			result = zoom * dpi * val_
+				/ 25.4; // 25.4
+			break;
+		case Length::PC:
+			// Pica: 1 pc = 12 pt
+			result = zoom * dpi * val_
+				/ (72.27 / 12); // 6.0225
+			break;
+		case Length::CC:
+			// Cicero: 1 cc = 12 dd
+			result = zoom * dpi * val_
+				/ (72.27 / (12 * 0.376 * 2.845)); // 5.6299779
+			break;
+		case Length::CM:
+			// Centimeter: 1 cm = 1/2.54 inch
+			result = zoom * dpi * val_
+				/ 2.54; // 2.54
+			break;
+		case Length::IN:
+			// Inch
+			result = zoom * dpi * val_;
+			break;
+		case Length::EX:
+			// Ex: The height of an "x"
+			// 0.4305 is the ration between 1ex and 1em in cmr10
+			result = val_ * em_width * 0.4305;
+			break;
+		case Length::EM:
+			// Em: The width of an "m"
+			result = val_ * em_width;
+			break;
+		case Length::MU:
+			// math unit = 1/18em
+			result = val_ * em_width / 18;
+			break;
+		case Length::PCW: // Always % of workarea
+		case Length::PTW:
+		case Length::PLW:
+			result = val_ * text_width / 100;
+			break;
+		case Length::PPW:
+			// paperwidth/textwidth is 1.7 for A4 paper with default margins
+			result = val_ * text_width * 1.7 / 100;
+			break;
+		case Length::PTH:
+			result = val_ * text_width * 1.787 / 100;
+			break;
+		case Length::PPH:
+			result = val_ * text_width * 2.2 / 100;
+			break;
+		case Length::UNIT_NONE:
+			result = 0;  // this cannot happen
+			break;
+		}
+	} // end of if kind_
 	return static_cast<int>(result + ((result >= 0) ? 0.5 : -0.5));
 }
 
@@ -296,23 +313,25 @@
 	// return any Length value as a one with
 	// the PostScript point, called bp (big points)
 	double result = 0.0;
-	switch (unit_) {
-	case Length::CM:
-		// 1bp = 0.2835cm
+	if (kind_ == LENGTH) {
+		switch (unit_) {
+		case Length::CM:
+			// 1bp = 0.2835cm
 		result = val_ * 28.346;
 		break;
-	case Length::MM:
-		// 1bp = 0.02835mm
-		result = val_ * 2.8346;
-		break;
-	case Length::IN:
-		// 1pt = 1/72in
-		result = val_ * 72.0;
-		break;
-	default:
-		// no other than bp possible
-		result = val_;
-		break;
+		case Length::MM:
+			// 1bp = 0.02835mm
+			result = val_ * 2.8346;
+			break;
+		case Length::IN:
+			// 1pt = 1/72in
+			result = val_ * 72.0;
+			break;
+		default:
+			// no other than bp possible
+			result = val_;
+			break;
+		}
 	}
 	return static_cast<int>(result + 0.5);
 }
Index: Length.h
===================================================================
--- Length.h	(revision 30641)
+++ Length.h	(working copy)
@@ -36,6 +36,12 @@
  */
 class Length {
 public:
+	/// The two kinds of lengths
+	enum HSpaceKind  {
+		DEFAULT,
+		LENGTH ///< user-defined length
+	};
+
 	/// length units
 	enum UNIT {
 		BP, ///< Big point (72bp = 1in), also PostScript point
@@ -62,10 +68,13 @@
 	///
 	Length();
 	///
+	Length(HSpaceKind h);
+	///
 	Length(double v, Length::UNIT u);
-
 	/// "data" must be a decimal number, followed by a unit
 	explicit Length(std::string const & data);
+	/// return the type of length
+	HSpaceKind kind() const { return kind_; }
 
 	///
 	void swap(Length & rhs);
@@ -100,6 +109,8 @@
 	friend bool isValidLength(std::string const & data, Length * result);
 
 private:
+	/// This HSpace kind
+	HSpaceKind kind_;
 	///
 	double val_;
 	///

Reply via email to