Возможности LibreOffice Draw
LibreOffice Draw позволяет создавать рисунки различной сложности и экспортировать их с использованием нескольких общепринятых форматов изображений. Кроме того, можно вставлять в рисунки таблицы, диаграммы, формулы и другие элементы, созданные в программах LibreOffice.
Векторная графика
Объекты векторной графики создаются в LibreOffice Draw с использованием линий и кривых, определенных с помощью математических векторов. Векторы описывают линии, эллипсы и многоугольники в соответствии с их геометрией.
Создание трёхмерных объектов
С помощью LibreOffice Draw можно создавать простые объёмные объекты, например, кубы, сферы и цилиндры и даже изменять освещение объектов.
Сетки и направляющие
Сетки и направляющие помогают визуально выровнять объекты в рисунке. Можно также выбрать привязку объекта к линии сетки, направляющей или к краю другого объекта.
Связывание объектов для отображения отношений
You can connect objects in LibreOffice Draw with special lines called «connectors» to show the relationship between objects. Connectors attach to gluepoints on drawing objects and remain attached when the connected objects are moved. Connectors are useful for creating organization charts and technical diagrams.
Отображение размеров
На технических диаграммах часто указываются размеры объектов на чертеже. В LibreOffice Draw размерные линии могут использоваться для расчета и отображения линейных размеров.
Галерея
Галерея содержит изображения, анимационные, звуковые и другие элементы, которые могут быть вставлены в рисунки или в другие программы LibreOffice.
Форматы графических файлов
Программа LibreOffice Draw позволяет экспортировать файлы в различных графических форматах, например, BMP, GIF, JPG и PNG.
LibreOffice: страшный сон бухгалтера

LibreOffice — мощный офисный пакет, который бесплатен для частного, образовательного и коммерческого использования. Его разработчики делают замечательный продукт, который во многих сферах используется в качестве альтернативы Microsoft Office. Команде PVS-Studio всегда интересно взглянуть на код таких известных проектов и попробовать найти в них ошибки. В этот раз сделать это было легко. Проект содержит много ошибок, которые могут привести к серьёзным проблемам. В статье будут рассмотрены некоторые интересные дефекты, найденные в коде.
Введение
LibreOffice — очень крупный C++ проект. Поддерживать проект такого объёма — сложная задача для команды разработчиков. И, к сожалению, складывается впечатление, что качеству кода LibreOffice не удаётся уделять достаточного внимания.
С одной стороны, проект просто огромный, не каждый инструмент статического или динамического анализа осилит анализ 13к файлов исходного кода. Столько файлов участвует в сборке офисного пакета вместе со сторонними библиотеками. В основном репозитории LibreOffice хранится около 8к файлов исходного кода. Такой объём кода создаёт проблемы не только разработчикам:

С другой стороны, у проекта много пользователей и требуется найти и исправить как можно больше ошибок. Каждая ошибка может причинять боль сотням и тысячам пользователей. Поэтому большой размер кодовой базы не должен становиться поводом отказаться от использования тех или иных инструментов, способных обнаружить ошибки. Думаю, читатель уже догадался, что речь идёт о статических анализаторах кода :).
Да, использование статических анализаторов не гарантирует отсутствия ошибок в проекте. Однако такие инструменты, как PVS-Studio, способны найти большое количество ошибок ещё на этапе разработки и тем самым уменьшить объём работ, связанных с отладкой и поддержкой проекта.
Давайте посмотрим, что можно найти интересного в исходных кодах LibreOffice, если взять статический анализатор кода PVS-Studio. Возможности запуска анализатора обширны: Windows, Linux, macOS. Для написания этого обзора использовался отчёт PVS-Studio, созданный при анализе проекта на Windows.
Изменения с последней проверки в 2015 году

В марте 2015 года был выполнен первый анализ LibreOffice («Проверка проекта LibreOffice») с помощью PVS-Studio. С тех пор офисный пакет сильно развился как продукт, но внутри всё также содержит множество ошибок. А некоторые паттерны ошибок вообще не поменялись с тех пор. Вот, например, ошибка из первой статьи:
V656 Variables ‘aVRP’, ‘aVPN’ are initialized through the call to the same function. It’s probably an error or un-optimized code. Consider inspecting the ‘rSceneCamera.GetVRP()’ expression. Check lines: 177, 178. viewcontactofe3dscene.cxx 178
Эта ошибка исправлена, но вот что нашлось в самой последней версии кода:
V656 Variables ‘aSdvURL’, ‘aStrURL’ are initialized through the call to the same function. It’s probably an error or un-optimized code. Consider inspecting the ‘pThm->GetSdvURL()’ expression. Check lines: 658, 659. gallery1.cxx 659
Как вы могли заметить, едва различимые составные имена функций до сих пор являются источником ошибок.
Ещё один интересный пример из старого кода:
V656 Variables ‘nDragW’, ‘nDragH’ are initialized through the call to the same function. It’s probably an error or un-optimized code. Consider inspecting the ‘rMSettings.GetStartDragWidth()’ expression. Check lines: 471, 472. winproc.cxx 472
Этот фрагмент кода действительно содержал ошибку, которая сейчас исправлена. Но ошибок в коде меньше не становится… Сейчас выявлена похожая ситуация:
V656 Variables ‘defaultZoomX’, ‘defaultZoomY’ are initialized through the call to the same function. It’s probably an error or un-optimized code. Consider inspecting the ‘pViewData->GetZoomX()’ expression. Check lines: 5673, 5674. gridwin.cxx 5674
Ошибки вносятся в код буквально по аналогии.
Не дай себя обмануть

V765 A compound assignment expression ‘x -= x — . ‘ is suspicious. Consider inspecting it for a possible error. swdtflvr.cxx 3509
Вот такой вот интересный «Hack» был найден с помощью диагностики V765. Если упростить строку кода с комментарием, то можно получить неожиданный результат:
И в чём тогда заключается Hack?
Ещё один пример на эту тему:
V567 The modification of the ‘nCount’ variable is unsequenced relative to another operation on the same variable. This may lead to undefined behavior. stgio.cxx 214
Выполнение кода в таких ситуациях может зависеть от компилятора и стандарта языка. Почему бы не переписать этот фрагмент кода проще, понятнее и надёжнее?
Как не надо использовать массивы и векторы

По какой-то причине кто-то понаделал множество однотипных ошибок при работе с массивами и векторами. Давайте разберём эти примеры.
V557 Array overrun is possible. The ‘nPageNum’ index is pointing beyond array bound. pptx-epptooxml.cxx 1168
Последним валидным индексом должно являться значение, равное size() — 1. Но в этом фрагменте кода допустили ситуацию, когда индекс nPageNum может иметь значение mpSlidesFSArray.size(), из-за чего происходит выход за пределы массива и работа с элементом, состоящим из «мусора».
V557 Array overrun is possible. The ‘mnSelectedMenu’ index is pointing beyond array bound. checklistmenu.cxx 826
Интересно, что в этом фрагменте кода написали проверку индекса более понятно, но при этом допустили такую же ошибку.
V557 Array overrun is possible. The ‘nXFIndex’ index is pointing beyond array bound. xestyle.cxx 2613
А эта ошибка вдвойне интереснее! В отладочном макросе написали правильную проверку индекса, а в другом месте снова сделали ошибку, допустив выход за пределы массива.
Теперь рассмотрим ошибку иного рода, не связанную с индексами.
V554 Incorrect use of shared_ptr. The memory allocated with ‘new []’ will be cleaned using ‘delete’. dx_vcltools.cxx 158
Этот фрагмент кода содержит ошибку, приводящую к неопределённому поведению программы. Дело в том, что память выделяется и освобождается разными способами. Для правильного освобождения памяти необходимо было объявить поле класса таким образом:
Как дважды ошибиться в макросах

V568 It’s odd that the argument of sizeof() operator is the ‘bTextFrame? aProps: aShapeProps’ expression. wpscontext.cxx 134
К сожалению для многих разработчиков, аргументы макросов ведут себя не как аргументы функций. Игнорирование этого факта часто приводит к ошибкам. В случаях #1 и #2 используется почти одинаковая конструкция с использованием тернарного оператора. Но в первом случае — макрос, во втором — функция. Однако это только вершина проблемы.
В случае #1 анализатор на самом деле обнаружил следующий код с ошибкой:
Это наш цикл с макросом SAL_N_ELEMENTS. Оператор sizeof не вычисляет выражение в тернарном операторе. В данном случае выполняется арифметика с размером указателей, результатом которой являются значения, далёкие от реального размера указанных массивов. На вычисление неправильных значений дополнительно влияет и разрядность приложения.
Но потом оказалось, что существует 2 макроса SAL_N_ELEMENTS! Т.е. препроцессор раскрыл не тот макрос, как же это могло произойти? Нам поможет определение макроса и комментарии разработчиков:
Другая версия макроса содержит безопасную шаблонную функцию, но что-то пошло не так:
- Безопасный макрос не включился в код;
- Другим макросом всё равно невозможно пользоваться, т.к. успешное инстанцирование шаблонной функции выполняется только если в тернарный оператор передать массивы одинакового размера. А в этом случае использование такого макроса теряет смысл.
Опечаточки и copy-paste

V1013 Suspicious subexpression f1.Pitch == f2.CharSet in a sequence of similar comparisons. xmldlg_export.cxx 1251
Ошибка является достойным кандидатом для пополнения статьи «Зло живёт в функциях сравнения», если мы когда-нибудь решим её обновить или расширить. Думаю, вероятность найти такую ошибку (пропуск f2.Pitch) самостоятельно крайне мала. А вы как считаете?
V501 There are identical sub-expressions ‘mpTable[ocArrayColSep] != mpTable[eOp]’ to the left and to the right of the ‘&&’ operator. formulacompiler.cxx 632
Результатом бездумного копирования стал такой фрагмент кода. Возможно, условное выражение просто продублировано лишний раз, но всё равно в коде не место таким неоднозначностям.
V517 The use of ‘if (A) <. >else if (A) <. >‘ pattern was detected. There is a probability of logical error presence. Check lines: 781, 783. mysqlc_databasemetadata.cxx 781
В результате копирования условных выражений, в коде была допущена ошибка, из-за которой значение 8 для переменной nColumnSize никогда не выставляется.
V523 The ‘then’ statement is equivalent to the ‘else’ statement. svdpdf.hxx 146
Тут перепутали функции min() и max(). Наверняка из-за этой опечатки в интерфейсе что-то странно масштабируется.
Странные циклы
V533 It is likely that a wrong variable is being incremented inside the ‘for’ operator. Consider reviewing ‘i’. javatypemaker.cxx 602
Выражение ++i в цикле выглядит очень подозрительно. Возможно, там должно быть ++j.
V756 The ‘nIndex2’ counter is not used inside a nested loop. Consider inspecting usage of ‘nIndex’ counter. treex.cxx 34
Есть какая-то ошибка во внутреннем цикле for. Т.к. переменная nIndex не изменяется, происходит перезаписывание одних и тех же двух элементов массива на каждой итерации. Скорее всего, везде вместо nIndex должна была использоваться переменная nIndex2.
V1008 Consider inspecting the ‘for’ operator. No more than one iteration of the loop will be performed. diagramhelper.cxx 292
Цикл for намеренно ограничивается до 1 итерации. Непонятно, зачем это сделано именно таким способом.
V612 An unconditional ‘return’ within a loop. pormulti.cxx 891
Пример более простого странного цикла из одной итерации, который лучше переписать на условный оператор.
Ещё несколько таких мест:
- V612 An unconditional ‘return’ within a loop. txtfrm.cxx 144
- V612 An unconditional ‘return’ within a loop. txtfrm.cxx 202
- V612 An unconditional ‘return’ within a loop. txtfrm.cxx 279
Странные условия

V637 Two opposite conditions were encountered. The second condition is always false. Check lines: 281, 285. authfld.cxx 281
Анализатор обнаружил противоречивые сравнения. Что-то с этим фрагментом кода явно не так.
Такой же код замечен и в этом месте:
- V637 Two opposite conditions were encountered. The second condition is always false. Check lines: 1827, 1829. doctxm.cxx 1827
Проблема приведённого фрагмента кода заключается в том, что первое условное выражение не влияет на результат всего выражения.
По мотивам подобных ошибок я даже написал теоретическую статью: «Логические выражения в C/C++. Как ошибаются профессионалы».
V590 Consider inspecting this expression. The expression is excessive or contains a misprint. unoobj.cxx 1895
Сразу не понять, в чём проблема данного условия, поэтому из препроцессированного файла был выписан развёрнутый фрагмент кода:
Получилось так, что ни одно число не входит одновременно в 4 диапазона, заданных в условии числами. Разработчики допустили ошибку.
V590 Consider inspecting the ‘* pData <= MAXLEVEL && * pData <= 9’ expression. The expression is excessive or contains a misprint. ww8par2.cxx 756
Из-за того, что в первом условии используется константа со значением 10, условие получилось избыточным. Этот фрагмент кода можно переписать следующим образом:
Но, возможно, в представленном коде была другая проблема.
V757 It is possible that an incorrect variable is compared with nullptr after type conversion using ‘dynamic_cast’. Check lines: 2709, 2710. menu.cxx 2709
Скорее всего, условие содержит ошибку. Необходимо было проверить указатели p и pPopup.
V668 There is no sense in testing the ‘m_pStream’ pointer against null, as the memory was allocated using the ‘new’ operator. The exception will be generated in the case of memory allocation error. zipfile.cxx 408
Анализатор обнаружил ситуацию, когда значение указателя, возвращаемого оператором new, сравнивается с нулём. Согласно стандарту языка C++, в случае невозможности выделения памяти, оператор new сгенерирует исключение std::bad_alloc. В проекте LibreOffice нашлось всего 45 подобных мест, что очень мало для такого объёма кода. Но всё равно это может приводить к проблемам у пользователей. Разработчикам следует убрать лишние проверки или создавать объекты таким образом:
V728 An excessive check can be simplified. The ‘(A && !B) || (!A && B)’ expression is equivalent to the ‘bool(A) != bool(B)’ expression. toolbox2.cxx 1042
Очень давно диагностика V728 была расширена до случаев, которые, скорое всего, не являются ошибочными, но усложняют код. А в сложном коде рано или поздно всё равно допускается ошибки.
Данное условие упрощается до такого:
В проекте встречается около 60 подобных конструкций, некоторые из них очень и очень громоздкие. Авторам проекта лучше ознакомиться с полным отчётом анализатора PVS-Studio.
Проблемы с безопасностью

V523 The ‘then’ statement is equivalent to the ‘else’ statement. docxattributeoutput.cxx 1571
Здесь скопирован очень крупный фрагмент кода. Для функции, которая изменяет некие права, выявленная проблема выглядит очень подозрительно.
V1001 The ‘DL’ variable is assigned but is not used by the end of the function. cipher.cxx 811
Переменные DL и DR обнуляются простым присваиванием в конце функции и больше не используются. Для компилятора это повод удалить команды для оптимизации.
Для правильной очистки переменных в Windows приложениях можно переписать код таким образом:
Но для LibreOffice здесь потребуется кросс-платформенное решение.
- V1001 The ‘DL’ variable is assigned but is not used by the end of the function. cipher.cxx 860
Обратите внимание, что в функции queryStream в списке параметров сначала идёт rPassword, а затем – rUri. В коде нашлось место, где соответствующие аргументы перепутаны местами при вызове этой функции.
V794 The assignment operator should be protected from the case of ‘this == &rToBeCopied’. hommatrixtemplate.hxx 121
Приведённый случай больше относится к безопасному написанию кода. В операторе копирования нет проверки на присвоение объекта самому себе. Всего в проекте около 30 таких реализаций оператора копирования.
Ошибки с SysAllocString

V649 There are two ‘if’ statements with identical conditional expressions. The first ‘if’ statement contains function return. This means that the second ‘if’ statement is senseless. Check lines: 125, 137. acctable.cxx 137
Функция SysAllocString() возвращает указатель, который может иметь значение NULL. Что-то странное написал автор этого кода. Указатель на аллоцированную память не проверяется, что может привести к проблемам в работе программы.
Похожие предупреждения из других функций:
- V649 There are two ‘if’ statements with identical conditional expressions. The first ‘if’ statement contains function return. This means that the second ‘if’ statement is senseless. Check lines: 344, 356. acctable.cxx 356
- V649 There are two ‘if’ statements with identical conditional expressions. The first ‘if’ statement contains function return. This means that the second ‘if’ statement is senseless. Check lines: 213, 219. trvlfrm.cxx 219
Результат одного из вызовов функции SysAllocString() не используется. Разработчикам следует обратить внимание на этот фрагмент кода.
Разное
V716 Suspicious type conversion in return statement: returned HRESULT, but function actually returns BOOL. maccessible.cxx 2649
Одна из ветвей исполнения функции возвращает значение, тип которого не соответствует типу возвращаемого значения функции. Тип HRESULT имеет более сложный формат, чем тип BOOL, и предназначен для хранения статусов операций. Например, значение E_INVALIDARG равно 0x80070057L. Правильно будет написать, например, так:
Более подробно об этом можно прочесть в документации к диагностике V716.
Ещё несколько подобных мест:
- V716 Suspicious type conversion in return statement: returned HRESULT, but function actually returns BOOL. inprocembobj.cxx 1299
- V716 Suspicious type conversion in return statement: returned HRESULT, but function actually returns BOOL. maccessible.cxx 2660
Согласно стандарту языка, порядок инициализации членов класса в конструкторе происходит в порядке их объявления в классе. В нашем случае поле m_aMutex будет инициализировано уже после того, как поучаствует в инициализации пяти других полей класса.
Вот как выглядит конструктор одного из полей класса:
Объект мьютекса передаётся по ссылке. В этом случае могут возникать разные проблемы: от обращения к неинициализированной памяти, до последующей потери изменений объекта.
V763 Parameter ‘nNativeNumberMode’ is always rewritten in function body before being used. calendar_jewish.cxx 286
Аргументы функции перезаписывают по разным причинам: борьба с предупреждениями компилятора, обратная совместимость, «костыль» и т.п. Тем не менее, любое из этих решений не является хорошим, а код выглядит запутанным.
Следует сделать обзор кода этого места и ещё несколько похожих:
- V763 Parameter ‘bExtendedInfo’ is always rewritten in function body before being used. graphicfilter2.cxx 442
- V763 Parameter ‘nVerbID’ is always rewritten in function body before being used. oleembed.cxx 841
- V763 Parameter ‘pCursor’ is always rewritten in function body before being used. edlingu.cxx 843
- V763 Parameter ‘pOutput’ is always rewritten in function body before being used. vnew.cxx 181
- V763 Parameter ‘pOutput’ is always rewritten in function body before being used. vnew.cxx 256
Заключение
Желание проверить код LibreOffice у меня появилось после личного использования продукта. По непонятной причине, при некоторых случайных запусках абсолютно из всех пунктов меню исчезает текст. Остаются только иконки и монотонные полоски. Ошибка, скорее всего, высокоуровневая и, возможно, её нельзя найти с помощью инструментов статического анализа. Тем не менее, анализатор нашёл очень много проблем, не связанных с этим, и я буду рад, если разработчики LibreOffice обратят внимание на статические анализаторы кода и попробуют использовать их для повышения качества и надёжности проекта. Это будет полезно всем.
Спасибо за внимание. Подписывайтесь на наши каналы и следите за новостями из мира программирования!
- Vk: @pvsstudio_rus
- Telegram: @pvsstudio_rus
- Instagram: @pvsstudio_rus
- Twitter: @pvsstudio_rus
- YouTube: @PVSStudioTool
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Svyatoslav Razmyslov. LibreOffice: Accountant’s Nightmare
Как сделать блок-схему или чертёж
Инструкция по использованию LibreOffice Draw
В этой статье мы научимся делать блок-схемы, в которых элементы соединены между собой линиями или стрелками и при перемещении элементов соединительные линии по-прежнему соединяют элементы. Чтобы было понятно, что имеется ввиду, взгляните на эту GIF.
Эта блок-схема сделана с помощью LibreOffice Draw.
Что такое Draw
Если коротко и просто, с помощью Draw можно рисовать схемы и чертежи, в которых элементы соединены между собой и их можно интерактивно перемещать. В результате уже в готовой схеме можно переместить элементы и не нужно заботится о соединительных линиях — они переместятся автоматически.
Ещё в Draw можно редактировать PDF файлы (и любые графические файлы).
Если говорить чуть более сложно, то Draw — это программа для векторной графики.
В привычной нам растровой графике, изображения состоят из точек в виде матрицы, информация о которых содержится в файле изображения.
А в векторной графике файл содержит математическое описания того, что находится на рисунке. Главное практическое следствие этого в том, что векторное изображение можно увеличивать сколько угодно и оно всегда будет чётким, поскольку новый вид при масштабировании вычисляется по математическим формулам.
А привычное нам растровое изображение, конечно же, при увеличении станет нечётким.
Эта инструкция поможет вам освоить первые шаги по использованию LibreOffice Draw. Несмотря на её простоту, вы узнаете много полезных приёмов и сможете строить отличные блок-схемы, в которых элементы можно перемещать не заботясь о соединительных линиях между ними.
Возможности LibreOffice Draw
LibreOffice Draw позволяет создавать рисунки различной сложности и экспортировать их с использованием нескольких общепринятых форматов изображений. Кроме того, можно вставлять в рисунки таблицы, диаграммы, формулы и другие элементы, созданные в программах LibreOffice.
Векторная графика
Объекты векторной графики создаются в LibreOffice Draw с использованием линий и кривых, определённых с помощью математических векторов. Векторы описывают линии, эллипсы и многоугольники в соответствии с их геометрией.
Создание трёхмерных объектов
С помощью LibreOffice Draw можно создавать простые объёмные объекты, например, кубы, сферы и цилиндры и даже изменять освещение объектов.
Сетки и направляющие
Сетки и направляющие помогают визуально выровнять объекты в рисунке. Можно также выбрать привязку объекта к линии сетки, направляющей или к краю другого объекта.
Связывание объектов для отображения отношений
Объекты LibreOffice Draw могут быть связаны специальными соединительными линиями для отображения отношений между объектами. Эти линии прикрепляются к точкам соединения на рисованных объектах и перемещаются вместе с ними. Соединительные линии полезны при создании организационных и технических диаграмм.
Отображение размеров
На технических диаграммах часто указываются размеры объектов на чертеже. В LibreOffice Draw размерные линии могут использоваться для расчёта и отображения линейных размеров.
Галерея
Галерея содержит изображения, анимационные, звуковые и другие элементы, которые могут быть вставлены в рисунки или в другие программы LibreOffice.
Форматы графических файлов
Программа LibreOffice Draw позволяет экспортировать файлы в различных графических форматах, например, BMP, GIF, JPG и PNG.
Бесплатная программа для векторной графики
Чтобы получить Draw, вам достаточно установить LibreOffice. Скачайте и установите последнюю версию LibreOffice с официального сайта: https://ru.libreoffice.org/download/
Как пользоваться LibreOffice Draw
Откройте Draw — автоматически будет создан новый файл.
В правой части экрана Draw вы увидите список фигур. Кликните на фигуру, которую вы хотите нарисовать, переместите курсор на область для рисования и зажав левую кнопку мыши перемещайте мышь до тех пор, пока фигура не примет нужный вам размер.
Как переместить или изменить размер фигуры
Кликните на фигуру, которую вы хотите переместить и нажмите левую кнопку мыши. Не отпуская левую кнопку переместите фигуру в любую часть холста.
Чтобы изменить размер фигуры, кликните по ней, чтобы выделить. Затем ухватив за любую ручку по периметру фигуры перетаскивайте её, пока фигура не пример нужный вам размер и форму.
Как добавить соединительные линии и стрелки
Создайте нужные вам фигуры.
Затем в разделе «Соединительные линии» выберите линию или стрелку, которая вам подходит.
Наведите курсор на первую фигуру — вы увидите метки, куда может быть подсоединён первый конец линии — выберите один из них, кликните и держите левую кнопку мыши.
Затем не отпуская левую кнопку мыши, наведите курсор на вторую фигуру — вы вновь увидите точки, куда можно закрепить второй конец соединительной линии — наведите на один из них и отпустите кнопку мыши.
Фигуры будут соединены.
Как написать текст внутри фигуры
Текст во внутрь фигуры можно вставить сразу несколькими способами. Любой из них начинается с того, что вам нужно выбрать фигуру, в которую вы хотите вставить текст — для этого просто кликните по фигуре левой кнопкой мыши.
- просто начните набирать текст — текстовое поле будет вставлено автоматически
- нажмите клавишу F2 для вставки текстового поля
- нажмите кнопку «Вставить текстовое поле»
Введите нужный вам текст.
Как поменять цвет фона для всех фигур
Кликните правой кнопкой мыши по любой из фигур и в открывшемся контекстном меню выберите «Изменить стиль».
В открывшемся окне выберите один из вариантов:
- Нет (отсутствие цвета)
- Цвет (сплошная заливка — по умолчанию)
- Градиент
- Текстура
- Орнамент
- Штриховка
Например, если вы выбрали Цвет, то кликните на новый цвет, который вы хотите, чтобы имели все фигуры.
Обратите внимание, что все остальные стили фигуры настраиваются в этом же окне.
Как поменять цвет фона только для одной фигуры
Кликните правой кнопкой мыши по фигуре, для которой вы хотите поменять цвет. В контекстном меню выберите «Область». Выберите новый цвет или другие варианты:
- Нет (отсутствие цвета)
- Цвет (сплошная заливка — по умолчанию)
- Градиент
- Текстура
- Орнамент
- Штриховка
Кликните на подходящий вам стиль, градиент, текстуру, орнамент или шриховку.
Как поменять цвет контура фигуры
Кликните правой кнопкой мыши по фигуре, для которой вы хотите поменять цвет. В контекстном меню выберите «Линия». Выберите цвет и другие настройки в открывшемся окне.
Нажмите ОК, чтобы настройки вступили в силу.
Сетка на листе для более точного позиционирования
Нажмите кнопку «Сетка», чтобы более точно позиционировать и устанавливать размер фигур.
Линии для более точного перемещения
Нажмите кнопку «Линии», в результате при каждом перемещении фигур или при изменении их размера будут появляться линии, чтобы помочь вам более точно сориентировать или выровнять фигуры относительно других элементов.
Как управлять сразу несколькими фигурами
Если вы хотите поменять стили (цвет фона, границы и прочее) или переместить, удалить или выполнить другие действия сразу с несколькими фигурами, то для этого выделите эти фигуры.
Чтобы выделить несколько фигур, поместите курсор мыши в стороне от них и, зажав левую кнопку мыши, двигайте курсор так, чтобы область получающегося квадрата охватила все нужные вам фигуры.
После этого вы можете удалить, переместить или отредактировать стиль сразу для нескольких фигур.
Как поменять цвет фона или контура сразу для нескольких фигур
Если вы хотите поменять стиль не для всех, а для нескольких фигур, то выделите их, как показано выше, нажмите правой кнопкой на любой из выделенных фигур и в контекстном меню выберите «Область» (для изменения фона фигур) или «Линия» (для изменения их цвета контура).
Как переместить фигуру на передний план или на задний план
Когда фигуры пересекаются, то одна из них оказывается под другой. Можно изменить, какая из фигур на переднем плане, а какая на заднем.
Для этого кликните правой кнопкой мыши по фигуре и в контекстном меню выберите «Расположить», затем выберите «Переместить вперёд» или «Переместить назад».
Как в Draw экспортировать в JPG или в PNG
Если вы нажмёте кнопку «Сохранить», то вам будет предложено сохранить редактируемый файл в формате .odg — это собственный формат Draw, в котором хранятся проекты. Чтобы сохранить в любом из распространённых форматах (JPG, PNG, GIF и многих других) в меню перейдите в «Файл» → «Экспорт».
В зависимости от выбранного формата, вам будет предложено установить опции файла.
Справка по LibreOffice Draw
Вам понравилась эта статья и вы хотите продолжения или у вас есть вопросы? Напишите об этом в комментариях и будет подготовлено продолжение по использованию Draw!