/** * Hide the atoms and bonds of a contracted abbreviation. If the abbreviations is attached we * remap the attachment symbol to display the name. If there are no attachments the symbol we be * added later ({@see #generateSgroups}). * * @param container molecule * @param sgroup abbreviation group display shortcut */ private static void contractAbbreviation( IAtomContainer container, Map<IAtom, String> symbolRemap, Sgroup sgroup) { final Set<IBond> crossing = sgroup.getBonds(); final Set<IAtom> atoms = sgroup.getAtoms(); // only do 0,1 attachments for now if (crossing.size() > 1) return; for (IAtom atom : atoms) { StandardGenerator.hide(atom); } for (IBond bond : container.bonds()) { if (atoms.contains(bond.getAtom(0)) || atoms.contains(bond.getAtom(1))) StandardGenerator.hide(bond); } for (IBond bond : crossing) { StandardGenerator.unhide(bond); IAtom a1 = bond.getAtom(0); IAtom a2 = bond.getAtom(1); StandardGenerator.unhide(a1); if (atoms.contains(a1)) symbolRemap.put(a1, sgroup.getSubscript()); StandardGenerator.unhide(a2); if (atoms.contains(a2)) symbolRemap.put(a2, sgroup.getSubscript()); } }
/** * If the molecule has display shortcuts (abbreviations or multiple group sgroups) certain parts * of the structure are hidden from display. This method marks the parts to hide and in the case * of abbreviations, remaps atom symbols. Appart from additional property flags, the molecule is * unchanged by this method. * * @param container molecule input * @param symbolRemap a map that will hold symbol remapping */ static void prepareDisplayShortcuts(IAtomContainer container, Map<IAtom, String> symbolRemap) { List<Sgroup> sgroups = container.getProperty(CDKConstants.CTAB_SGROUPS); if (sgroups == null || sgroups.isEmpty()) return; // select abbreviations that should be contracted for (Sgroup sgroup : sgroups) { if (sgroup.getType() == SgroupType.CtabAbbreviation) { Boolean expansion = sgroup.getValue(SgroupKey.CtabExpansion); // abbreviation is displayed as expanded if (expansion != null && expansion == Boolean.TRUE) continue; // no or empty label, skip it if (sgroup.getSubscript() == null || sgroup.getSubscript().isEmpty()) continue; contractAbbreviation(container, symbolRemap, sgroup); } else if (sgroup.getType() == SgroupType.CtabMultipleGroup) { hideMultipleParts(container, sgroup); } } }
private IRenderingElement generateAbbreviationSgroup(Sgroup sgroup) { String label = sgroup.getSubscript(); // already handled by symbol remapping if (sgroup.getBonds().size() > 0 || label == null || label.isEmpty()) { return new ElementGroup(); } // we're showing a label where there were no atoms before, we put it in the // middle of all of those which were hidden final Point2d labelCoords = GeometryUtil.get2DCenter(sgroup.getAtoms()); ElementGroup group = new ElementGroup(); for (Shape outline : atomGenerator .generatePseudoSymbol(label, HydrogenPosition.Right) .resize(1 / scale, 1 / -scale) .getOutlines()) group.add(GeneralPath.shapeOf(outline, foreground)); return MarkedElement.markupAtom(group, null); }