/* Hyphenate a word completely. */ static PyObject * Hyphen_hyphenate(Hyphenobject *self, PyObject *args) { const char *word; char *buffer; char *scratch; PyObject* result; const int BORDER = 2; if (!PyArg_ParseTuple(args, "s", &word)) /* No word to hyphenate */ return NULL; buffer = malloc(sizeof(char) * (strlen(word)+BORDER+1)); if (buffer == NULL) { PyErr_NoMemory(); return NULL; /* out of memory */ } hnj_hyphen_hyphenate(self->hdict, word, strlen(word), buffer); scratch = (char*) malloc(sizeof(char) * (strlen(word) + countHyphenIntegers(buffer) + 1)); if(scratch == NULL) { PyErr_NoMemory(); free(buffer); buffer = NULL; /* out of memory */ return NULL; } placeHyphens(word, buffer, scratch); free(buffer); if((result = Py_BuildValue("s", scratch)) == NULL) { free(scratch); return NULL; } free(scratch); return result; }
void breakLine(QString& str, QString& after, int textWidth) { if (str.length() <= textWidth) { return; } // Найти слово, которое находится на границе textWidth. int beginWordPosition = str.lastIndexOf(' ', textWidth - 1) + 1; int endWordPosition = str.indexOf(' ', textWidth - 1) - 1; // Граничное слово находится в конце строки. if (endWordPosition == -2) { endWordPosition = str.length() - 1; } // Слово состоит из одной буквы. if (beginWordPosition == endWordPosition + 2) { endWordPosition = beginWordPosition; } int wordLength = endWordPosition - beginWordPosition + 1; QString word = str.mid(beginWordPosition, wordLength); // Слово начинается на границе ширины текста. if (beginWordPosition == textWidth - 1 && wordLength != 1) { QString temp = str.left(textWidth - 1); after = str.right(str.length() - temp.length()); temp = temp.trimmed(); if (temp.length() < textWidth) { fillSpaces(temp, textWidth); } str = temp.trimmed(); return; } // Расставить в слове мягкие переносы. placeHyphens(word, word); // В слове нельзя сделать перенос. if (word.count('\1') == 0) { // Слово целиком умещается в ширину текста. if (beginWordPosition + wordLength <= textWidth) { after = str.right(str.length() - textWidth).trimmed(); str.chop(str.length() - textWidth); str = str.trimmed(); if (str.length() < textWidth) { fillSpaces(str, textWidth); } str = str.trimmed(); return; } else { QString temp = str.left(textWidth); after = str.right(str.length() - temp.length()); str = temp.trimmed(); if (str.length() < textWidth) { fillSpaces(str, textWidth); } str = str.trimmed(); return; } } // Вычислить максимальную длину слова до переноса, как разницу индексов // максимально допустимого символа, умещающегося в ширину текста, и начала // слова (символ переноса не входит в эту длину). int maxWordLengthBeforeBreak = (textWidth - 1) - beginWordPosition; // Так как в слове появились мягкие переносы, то нужно увеличить // максимальную длину слова до переноса на количество символов, // встретившихся перед прежней длиной. for (int i = 0; i < maxWordLengthBeforeBreak; ++i) { if (word[i] == '\1') { ++maxWordLengthBeforeBreak; } } if (word[maxWordLengthBeforeBreak] == '\1') { ++maxWordLengthBeforeBreak; } // Индекс переноса. int breakIndex = word.lastIndexOf('\1', maxWordLengthBeforeBreak - 1); // В слове можно сделать перенос с учетом ограничения на длину. if (breakIndex != -1) { // Заменить мягкий перенос на '\2' в позиции, не превышающей // максимальную длину слова до переноса. Замена производится именно на // '\2', а не на знак дефиса, т. к. в строке уже может быть знак дефиса. // Иначе не получится легко определить индекс, где нужно разделить // строки на две. word[breakIndex] = '\2'; // Удалить все мягкие переносы. word.replace('\1', ""); // Вставить слово с переносом в строку. str.remove(beginWordPosition, wordLength); str.insert(beginWordPosition, word); // Разделить строку на две. QStringList strings = str.split('\2'); str = strings[0] + "-"; if (str.length() < textWidth) { fillSpaces(str, textWidth); } after = strings[1]; str = str.trimmed(); } // В слове нельзя сделать перенос с учетом ограничения на длину. // Разделяем строку по границе начала граничного слова. else { after = str.right(str.length() - beginWordPosition); str.chop(str.length() - beginWordPosition); if (str.length() < textWidth) { fillSpaces(str, textWidth); } str = str.trimmed(); } }